
#include "Common.h"
#include "String.h"
#include "SharedPtr.h"
#include "ResourceManager.h"
#include "StringConverter.h"
#include "NGLog.h"
#include "MersenneTwister.h"
#include "ScriptMgr.h"
#include "Threading/Mutex.h"
#include "Util.h"
#include "Message.h"
#include "Effects.h"
#include "WorldPacket.h"
#include "Character.h"
#include "CharManager.h"
#include "Regions.h"
#include "RegionManager.h"
#include "WSSocket.h"
#include "Database/DatabaseEnv.h"
#include "json/json.h"

#include "GameDataEnum.h"
#include "ProtocolDealEnums.h"
#include "ProtocolsManager.h"
#include "ResourceEventEnum.h"
#include "AIInterface.h"
#include "AIScript.h"
#include "GameThreadLogic.h"
#include "VipCardManager.h"
#include "CenterBankManager.h"
#include "Tools.h"
#include "CenterBattleManager.h"
#include "CenterBattleLogManager.h"
#include "MJGameLogic.h"
#include "MJStruct.h"
#include "GameDefine.h"
#include "OpcodesEx.h"
#include LOGIC_MGR_PATH
#include LOG_MGR_PATH
#include PROTOCOLS_MGR_PATH
#include XMLDATA_MGR_PATH

#define START_PLAYER_NUM  4
#define INIT_POS 255
#ifdef MJPUBLIC
namespace AIScript {

	// 构造函数
	AIMaJiangChannelBaseInterface::AIMaJiangChannelBaseInterface(Resource * pUnit) :AIChannelBaseInterface(pUnit)
	{
		m_AIType = AITYPE_WCHANNEL;
		m_GameLogic = NULL;
		publicBattelStateInit = NULL;
		publicBattelUpdate = NULL;
		m_nRoundId = 0;
		m_nExit_coins = 0;
		m_bDealDuiJuFei = true;
	}

	AIMaJiangChannelBaseInterface::~AIMaJiangChannelBaseInterface()
	{
		TablePlayerIter iter, ei = m_vSeatPlayers.end();
		for (iter = m_vSeatPlayers.begin(); iter != ei; ++iter)
		{
			if ((*iter) != NULL)
			{
				delete *iter;
			}
			*iter = NULL;
		}
		m_vSeatPlayers.clear();
		if (m_GameLogic != NULL)
		{
			delete m_GameLogic;
		}
		m_GameLogic = NULL;
	}

	// 加载函数
	void AIMaJiangChannelBaseInterface::Load()
	{

		Log.Debug("AIMaJiangChannelBaseInterface::Load", "Load");

		InitGameLogic();
		m_i8SwapCardsPosType = -1;
		m_vSeatPlayers.clear();
		m_mapWatchPlayers.clear();
		m_ui8FengQuanLoopCount = 0;
		m_run_status = en_MJChannelState_Init;
		m_next_run_status = en_MJChannelState_Init;

		m_curStartPos = INIT_POS;

		m_ui8BankerPos = INVALID_uint8;
		m_ui8NextBankerPos = INVALID_uint8;
		m_ui8DongFengSeat = INVALID_uint8;
		m_bOutMagicCard = m_GameLogic->IsOutMagicCard();;
		m_uint8MaxCardNum = m_GameLogic->GetMJMaxCardNum();
		m_nTimeoutTimer = m_GameLogic->GetChannelTime("ChannelOverTime");
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::Load", "m_uint8MaxCardNum:%d", m_uint8MaxCardNum);


		m_ui8StartTestCardsIndex = m_GameLogic->GetTestCardsStartIndex();

		m_ui8RoundMode = m_GameLogic->GetRoundMode();

		m_ui8LiuJuCardNum = m_GameLogic->GetLiuJuCardNum();

		m_nGameModeFlag = m_GameLogic->GetGameMode();

		m_bOutCardTingList = m_GameLogic->GetOutCardTingList();

		m_bShowConstantlyCale = m_GameLogic->GetShowConstantlyCale();

		m_nSwapCardsWaitTimer = m_GameLogic->GetChannelTime("SwapCardsWaitTimer");
		m_nChooseQueWaitTimer = m_GameLogic->GetChannelTime("ChooseQueWaitTimer");

		m_nAHuPaiTime = m_GameLogic->GetChannelTime("AHuPaiTime");
		m_nCastHandCardTime = m_GameLogic->GetChannelTime("CastHandCardTime");
		m_nAGiveHandCardTime = m_GameLogic->GetChannelTime("AGiveHandCardTime");
		m_nOperatorCardTime = m_GameLogic->GetChannelTime("OperatorCardTime");
		m_nSendInitalCardsWaitTimer = m_GameLogic->GetChannelTime("SendInitalCardsWaitTimer");
		m_nChooseBankerWaitTimer = m_GameLogic->GetChannelTime("ChooseBankerWaitTimer");
		m_bOverTimeWait = m_GameLogic->IsOperateStateOverTimeTrusteeship();
		m_nSameIPCheckTimer = m_GameLogic->GetChannelTime("SameIPCheckTimer");
		m_ui8MaxHandCount = m_GameLogic->GetMaxHandCardCount();
		m_bQiangGangHu = false;
		m_bSameIPCheck = m_GameLogic->GetSameIPCheck();
		m_bHaveSameIP = true;
		m_canWaitTime = 0;
		m_nStartPlayerNum = 0;
		m_nMaxPlayerNum = 0;
		m_nWarPlayerNum = 0;
		m_nLoopId = 0;
		m_bVoting = false;
		m_nVoteOverTime = 0;
		m_bNormalExit = true;													// 是否正常退出
		m_bPreCalc = false;
		m_bDissolve = false;
		m_nLimitLoop = 0;

		m_bGameOver = false;
		m_nDissolveReson = 0;
		m_nGameStartTime = 0;
		m_nCreateTime = time(0);
		m_nTingQianChangTimer = time(0);
		m_nTopTimes = 0;
		m_nFzPid = 0;
		m_nBasePoint = 0;
		m_nLimitLoop = 0;
		m_nLimitTime = 0;
		m_nGameID = 0;
		m_nGzid = 0;
		m_nMode = 0;
		m_strPlayJsonData = "";

		m_btLog.Init();

		InitPublicFun();

		initialize();

		// 初始座位列表
		InitPlayerSeatList();
		HSM_INIT_(&AIMaJiangChannelBaseInterface::battle_init);
	}

	// 初始函数
	void AIMaJiangChannelBaseInterface::initialize()
	{
		m_dice.clear();
		m_dice.assign(4, 0);
		m_uint8RepertoryCard.clear();

		m_bInitCenterData = false;
		m_status_endtimer = 0;
		m_status_starttimer = 0;

		initCenterBattleInfo();

		if (m_nMaxPlayerNum == 0)
		{
			Log.Error("AIMaJiangChannelBaseInterface::initialize", "Channel[%u] cb_id[%u]", m_Unit->getHandle(), m_nCB_id);
			ASSERT(false);
		}

		RepositionSink();
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
				pTp->init();
		}
		//	m_bHaveSameIP = true;
			//// 生成牌
			//CreateCards();
			//// 洗牌
			//ShuffleCards();
			// 初始组局数据
	}

	// 初始棋牌圈数据
	void AIMaJiangChannelBaseInterface::initCenterBattleInfo(void)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::initCenterBattleInfo", "initCenterBattleInfo");
		Json::Reader reader;
		Json::Value val;
		reader.parse(m_Unit->getStringField("info"), val);

		if (val.isMember("cb_id"))
		{// 组局ID
			m_btLog.cb_id = val["cb_id"].asUInt();
			m_nCB_id = m_btLog.cb_id;
		}
		
		


		if (val.isMember("fz_pid"))
		{// 房主PID
			m_nFzPid = val["fz_pid"].asUInt();
		}

		if (val.isMember("base_coins"))
		{// 底分
			m_nBasePoint = val["base_coins"].asUInt();
		}

		if (val.isMember("limit_loop"))
		{// 限制轮次
			m_nLimitLoop = val["limit_loop"].asUInt();
			m_nLimitRound = val["limit_loop"].asUInt();
		}
		if (val.isMember("limit_round"))
		{// 限制轮次
			m_nLimitRound = val["limit_round"].asUInt();
		}
		if (val.isMember("exit_coins"))
		{// 退场金币
			m_nExit_coins = val["exit_coins"].asUInt();
		}
		
		if (val.isMember("limit_time"))
		{// 限制时间
			m_nLimitTime = val["limit_time"].asUInt();
		}

		if (val.isMember("top_times"))
		{// 封顶倍数
			m_nTopTimes = val["top_times"].asUInt();
		}

		if (val.isMember("game_id"))
		{// 游戏ID
			m_nGameID = val["game_id"].asUInt();
			m_btLog.game_id = m_nGameID;
		}

		if (val.isMember("gz_id"))
		{
			m_nGzid = val["gz_id"].asUInt();
		}

		if (val.isMember("mode"))
		{
			m_nMode = val["mode"].asUInt();
			m_btLog.mode = m_nMode;
		}

		Json::FastWriter w;
		//附加数据
		if (val.isMember("extra_data"))
		{
			Json::Value val2 = val["extra_data"];
			if (val2.isMember("playerSum"))
			{// 最大玩家数量
				m_nMaxPlayerNum = val2["playerSum"].asUInt();
			}
			if (val2.isMember("pay_mode"))
			{// 最大玩家数量
				m_ui8PayMode = val2["pay_mode"].asUInt();
			}
			if (val2.isMember("typeDengRen"))
			{// 死等
				if (val2["typeDengRen"].asUInt() == 2)
				{
					m_bOverTimeWait = false;
				}
				else
					m_bOverTimeWait = true;
			}
			if (val2.isMember("exit_coins"))
			{// 退场金币
				m_nExit_coins = val2["exit_coins"].asUInt();
			}
			if (val2.isMember("club_id"))
			{// 俱乐部ID
				m_btLog.club_id = val2["club_id"].asUInt();
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::initCenterBattleInfo", "m_btLog.club_id[%d]", m_btLog.club_id);
			}
			else
				m_btLog.club_id = 0;
			if (val2.isMember("club_room_id"))
			{// 俱乐部房间ID
				m_btLog.club_room_id = val2["club_room_id"].asUInt();
			}
			else
				m_btLog.club_room_id = 0;
		}

		// 房间ID
		val["join_code"] = m_Unit->getStringField("winner");
		// 开始时间
		val["start_time"] = m_nGameStartTime;
		// 当前轮次
		val["curr_loop"] = m_nLoopId;
		val["curr_round"] = m_nRoundId;
		m_nStartPlayerNum = m_nMaxPlayerNum;

		m_btLog.player_winLose.clear();
		m_bInitCenterData = true;

		CenterBattle cb;
		sCenterBattleMgr.GetCenterBattle(m_btLog.cb_id, &cb);
		m_btLog.agent_id = cb.reg_from;
		val["pay_num"] = cb.data2;

		m_strPlayJsonData = w.write(val);
	}

	// 生成牌
	void AIMaJiangChannelBaseInterface::CreateCards()
	{
		for (int i = en_MJColor_Wan; i <= en_MJColor_Tiao; ++i)
		{
			for (int j = 1; j < 10; ++j)
			{
				uint32 card = MAKE_CARD(i, j);
				m_uint8RepertoryCard.push_back(card);
				m_uint8RepertoryCard.push_back(card);
				m_uint8RepertoryCard.push_back(card);
				m_uint8RepertoryCard.push_back(card);
			}
		}
	}

	// 洗牌
	void AIMaJiangChannelBaseInterface::ShuffleCards()
	{
		int num = RandomUInt(sXmlDataMgr.GetConfXMLValue("COMMON_MJ_MIN_WASHCARDS_COUNT"), sXmlDataMgr.GetConfXMLValue("COMMON_MJ_MAX_WASHCARDS_COUNT"));
		for (int i = 0; i < num; ++i)
		{
			uint32 index = RandomUInt(m_uint8RepertoryCard.size() - 1);
			uint32 index1 = RandomUInt(m_uint8RepertoryCard.size() - 1);
			uint32 temp = m_uint8RepertoryCard[index];
			m_uint8RepertoryCard[index] = m_uint8RepertoryCard[index1];
			m_uint8RepertoryCard[index1] = temp;
		}
	}

	//复位牌桌
	void AIMaJiangChannelBaseInterface::RepositionSink()
	{

		//游戏数据
		m_ui8SiceCount = 0;
		VecInit<uint8>(m_ui8LastAction, m_nMaxPlayerNum, 0);


		//玩家手牌列表   索引值
		std::vector<uint8> m_ui8VecUserCardIndexTemp(MAX_INDEX, 0);
		VecInit<std::vector<uint8> >(m_ui8UserCardIndex, m_nMaxPlayerNum, m_ui8VecUserCardIndexTemp);
		//不能出牌列表
		VecInit<std::vector<uint8> >(m_vecNoOutCardsIndex, m_nMaxPlayerNum, m_ui8VecUserCardIndexTemp);
		std::vector<uint8> m_vecPlayerTingPaiTiShiTemp;

		VecInit<std::vector<uint8> >(m_vecPlayerTingPaiTiShi, m_nMaxPlayerNum, m_vecPlayerTingPaiTiShiTemp);
		//玩家游戏状态  掉线托管
		m_ui8Trustee.clear();
		m_ui8Trustee.assign(m_nMaxPlayerNum, enPlayer_Normal);

		//玩家是否能继续游戏
		VecInit<uint8>(m_bPlayStatus, m_nMaxPlayerNum, true);


		//玩家所缺花色
		VecInit<uint8>(m_ui8QueColor, m_nMaxPlayerNum, 0);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			//m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::RepositionSink", "m_ui8QueColor[%d]:%d", i, m_ui8QueColor[i]);
		}
		//玩家是否胡牌
		VecInit<uint8>(m_bHasHuPai, m_nMaxPlayerNum, false);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			//m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::RepositionSink", "m_bHasHuPai[%d]:%d", i, m_bHasHuPai[i]);
		}
		m_ui8GangPlayer = INVALID_uint8;


		//用户状态

		//玩家操作响应
		VecInit<uint8>(m_bResponse, m_nMaxPlayerNum, 0);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			//m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::RepositionSink", "m_bResponse[%d]:%d", i, m_bResponse[i]);
		}

		//漏胡
		VecInit<std::vector<uint8> >(m_vecLouHuCards, m_nMaxPlayerNum, std::vector<uint8>());

		//玩家操作
		VecInit<uint8>(m_ui8UserAction, m_nMaxPlayerNum, 0);

		//玩家实际操作扑克
		VecInit<uint8>(m_ui8OperateCard, m_nMaxPlayerNum, 0);

		//玩家实际执行操作
		VecInit<uint8>(m_ui8PerformAction, m_nMaxPlayerNum, 0);

		//实际操作牌列表
		std::vector<uint8>  m_ui8TargetCardDataTemp;
		VecInit<std::vector<uint8> >(m_ui8TargetCardData, m_nMaxPlayerNum, m_ui8TargetCardDataTemp);

		//用户状态
		m_bSendStatus = true;
		m_bGangStatus = false;
		m_bGangOutStatus = false;
		m_bGangKai = false;
		m_bBuPai = false;
		//是否禁止吃胡  
		VecInit<uint8>(m_bEnjoinChiHu, m_nMaxPlayerNum, 0);

		//是否禁止吃碰
		VecInit<uint8>(m_bEnjoinChiPeng, m_nMaxPlayerNum, 0);

		//是否报叫
		VecInit<uint8>(m_bBaoJiao, m_nMaxPlayerNum, 0);

		//是否震听
		VecInit<uint8>(m_bGuoShui, m_nMaxPlayerNum, 0);

		//起手补牌状态
		VecInit<uint8>(m_vecStartBuPaiStatus, m_nMaxPlayerNum, 0);

		//发牌信息
		m_uint8SendCardData = 0;
		m_uint8SendCardCount = 0;
		m_uint8LeftCardCount = m_uint8MaxCardNum;
		//m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::RepositionSink", "m_uint8LeftCardCount:%d", m_uint8LeftCardCount);
		//麻将库
		VecInit<uint8>(m_uint8RepertoryCard, m_uint8MaxCardNum, 0);


		//牌墙
		m_ui8HeapHand = INVALID_uint8;
		m_ui8HeapTail = INVALID_uint8;

		//麻将牌墙
		std::vector<uint8>   m_ui8HeapCardInfoTemp(2, 0);
		VecInit<std::vector<uint8> >(m_ui8HeapCardInfo, 4, m_ui8HeapCardInfoTemp);


		//出牌信息
		m_ui8OutCardPos = INVALID_uint8;
		m_ui8OutCardData = 0;
		m_ui8OutCardCount = 0;
		////各个玩家弃牌数
		//VecInit<uint8>(m_ui8DiscardCount, m_nMaxPlayerNum, 0);
		//各个玩家弃牌统计
		std::vector<uint8>  m_ui8DiscardCountTemp;
		VecInit<std::vector<uint8> >(m_ui8DiscardCard, m_nMaxPlayerNum, m_ui8DiscardCountTemp);
		//各个玩家癞子牌列表
		VecInit<std::vector<uint8> >(m_ui8MagicCardsList, m_nMaxPlayerNum, m_ui8DiscardCountTemp);


		m_bAnyOperate = false;

		//吃碰杠
		std::vector<tagWeaveItem>  m_WeaveItemArrayTemp;
		m_WeaveItemArray.clear();
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			m_WeaveItemArray.push_back(m_WeaveItemArrayTemp);
		}


		//发牌信息
		m_ui8ProvideCard = 0;
		m_ui8ProvidePos = INVALID_uint8;
		m_ui8CurrentPos = INVALID_uint8;
		m_ui8ResumePos = INVALID_uint8;

		//结束信息
		m_ui8QiangGangProvideCard = 0;
		m_ui8QiangGangProvidePos = INVALID_uint8;
		m_ui8AllPlayerOperatorStatus = false;
		m_ui8ChiHuCard = 0;
		//玩家胡牌结果
		VecInit<uint32>(m_ui32ChiHuKind, m_nMaxPlayerNum, 0);
		//得分结果
		VecInit<CChiHuRight>(m_ChiHuRight, m_nMaxPlayerNum, CChiHuRight());

		////马牌列表
		//VecInit<uint8>(m_ui8MaPaiList, m_ui8MaxMaPaiNum, 0);
		m_ui8MaPaiList.clear();
		//m_ui8MaPaiNum = 0;

		//玩家听牌列表
		std::map<uint8, std::vector<uint8> > m_MPlayerTingCardListTemp;
		VecInit<std::map<uint8, std::vector<uint8> > >(m_MPlayerTingCardList, m_nMaxPlayerNum, m_MPlayerTingCardListTemp);

		//玩家碰牌
		VecInit<std::vector<std::vector<uint8> > >(m_VPlayerPengCardList, m_nMaxPlayerNum, std::vector<std::vector<uint8> >());

		//玩家杠牌列表
		VecInit<std::vector<std::vector<uint8> > >(m_VPlayerGangCardList, m_nMaxPlayerNum, std::vector<std::vector<uint8> >());

		//玩家吃牌列表
		VecInit<std::vector<std::vector<uint8> > >(m_VPlayerChiCardList, m_nMaxPlayerNum, std::vector<std::vector<uint8> >());

		//一炮多响状态
		VecInit<uint8>(m_ui8YiPaoDuoXiangList, m_nMaxPlayerNum, 0);

		//换牌列表
		VecInit<std::vector<uint8> >(m_vecSwapCards, m_nMaxPlayerNum, std::vector<uint8>());

		//选缺列表
		VecInit<uint8>(m_ui8QueColor, m_nMaxPlayerNum, 0);


		//花牌
		VecInit<std::vector<uint8> >(m_ui8HuaPaiList, m_nMaxPlayerNum, std::vector<uint8 >());

		//混乱扑克
		m_GameLogic->ShuffleCards(m_uint8RepertoryCard, m_uint8MaxCardNum);
		for (uint8 i = 0; i < m_uint8RepertoryCard.size(); i++)
		{
			//m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::RepositionSink", "m_uint8RepertoryCard[%d]:%d", i, m_uint8RepertoryCard[i]);
		}
		m_vecPlayerConstantlyCaleList.clear();
	}


	uint8 AIMaJiangChannelBaseInterface::GiveFreeGift(CharPtr & pChr, const uint32 & char_id, const uint8 & gift_id)
	{
		if (pChr.isNull())
			return 0;

		uint32 src_charID = pChr->getHandle();
		if (src_charID == char_id)	// 不能给自己赠送鲜花
			return 0;

		uint8 result = 1;
		std::vector<uint32> vRecvCharIDs;

		TablePlayerIter iter, ei = m_vSeatPlayers.end();
		for (iter = m_vSeatPlayers.begin(); iter != ei; ++iter)
		{
			if ((*iter)->player.isNull())
				continue;

			if ((*iter)->player._handle == src_charID)
				continue;

			if (char_id == 0)
			{// 给所有玩家
				vRecvCharIDs.push_back((*iter)->player._handle);
			}
			else
			{// 给指定玩家
				if ((*iter)->player._handle == char_id)
				{
					vRecvCharIDs.push_back(char_id);
					break;
				}
			}
		}
		// 没有可赠送的玩家
		if (vRecvCharIDs.empty())
			result = 0;

		WorldPacket packet;
		if (result == 1)
		{// 成功
			if (sProtocolsMgr.CreateGiveFreeGiftPacket(&packet, src_charID, gift_id, vRecvCharIDs, result))
				BroadcastPacket(&packet);
		}
		else
		{// 失败
			if (sProtocolsMgr.CreateGiveFreeGiftPacket(&packet, src_charID, gift_id, vRecvCharIDs, result))
				sGLMgr.SendProtocolsToChr(pChr, &packet);
		}

		return 0;
	}

	//获取牌桌中总人数
	uint8 AIMaJiangChannelBaseInterface::GetNowPlayerNum()
	{
		WGS_MJCHANNEL_LOCK;

		uint8 ui8Count = 0;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (GetTablePlayerByPos(i) != NULL)
			{
				ui8Count++;
			}
		}
		return ui8Count + m_mapWatchPlayers.size();
	}

	//初始化GameLogic
	void AIMaJiangChannelBaseInterface::InitGameLogic()
	{
		m_GameLogic = ::MJGameLogic::CreateGameLogic(m_Unit->getUInt32Field("ai"));

		if (m_GameLogic == NULL)
		{
			Log.Error("AIMaJiangChannelBaseInterface::InitGameLogic", "Create m_GameLogic FAILED ai:%d", m_Unit->getUInt32Field("ai"));
			ASSERT(false);
		}
	}



	// 帧循环
	void AIMaJiangChannelBaseInterface::Update(const uint32 & p_time)
	{
		//Log.Debug("AIMaJiangChannelBaseInterface::Update", "Dm_nVoteOverTime:%d", m_nVoteOverTime);
		//if (m_nVoteOverTime)
		//{// 检测投票自动逻辑
		//	Log.Debug("AIMaJiangChannelBaseInterface::Update", "Deal Vote OverTime 1 m_nVoteOverTime:%d time(0):%d m_bVoting:%d", m_nVoteOverTime, time(0), m_bVoting);
		//	if ((time(0) >= m_nVoteOverTime) && m_bVoting)
		//	{
		//		Log.Debug("AIMaJiangChannelBaseInterface::Update", "Deal Vote OverTime 2");
		//		std::map<uint32, stVotePlayer> tempVotePlayers;

		//		{
		//	//		WGS_MJCHANNEL_LOCK;
		//			WGS_MJCHANNEL_VOTE_LOCK;
		//				tempVotePlayers = m_mapVotePlayers;
		//		}
		//		Log.Debug("AIMaJiangChannelBaseInterface::Update", "Deal Vote OverTime 3");
		//		std::map<uint32, stVotePlayer>::iterator itVote, eiVote = tempVotePlayers.end();
		//		for (itVote = tempVotePlayers.begin(); itVote != eiVote; ++itVote)
		//		{
		//			if (itVote->second.vote_status)
		//				continue;

		//			CharPtr pChr = sCharMgr.load(itVote->first);
		//			PlayerDealVoteLock(pChr, voteType_Agree);
		//		}
		//	}
		//}

	//	if (m_ui8PayMode == 3)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL)continue;
				if (pTp->m_ui32ExitChannelTime != 0)
				{
					if (time(0) - pTp->m_ui32ExitChannelTime >= m_GameLogic->GetChannelTime("ExitChannelTime"))
					{
						pTp->m_ui32ExitChannelTime = 0;
						m_ui8Trustee[pTp->pos] = enPlayer_OffLine;
						WorldPacket packet;
						if (sProtocolsMgr.CreateMJPlayerStatusPacket(&packet, pTp->pos, enPlayer_OffLine))
							BroadcastPacket(&packet);
					}
				}
			}
			if (m_nTimeoutTimer != 0 && time(0) - m_nTingQianChangTimer >= m_nTimeoutTimer && m_btLog.club_id == 0)
			{
				m_bGameOver = true;
				m_nDissolveReson = DissolveType_Life;
				m_next_run_status = en_MJChannelState_GameOverCalc;
				m_nTimeoutTimer = 0;
			}
			
		}


		if (!m_nNextCheckTimeoutTime)
		{// 检测
			if (time(0) - m_nCreateTime >= sXmlDataMgr.GetConfXMLValue("CENTER_BATTLE_MAX_WAITTIMER"))
			{// 牌桌超时结束
				m_bGameOver = true;
				m_nDissolveReson = DissolveType_Life;
				m_next_run_status = en_MJChannelState_GameOverCalc;

				m_nNextCheckTimeoutTime = time(0);
			}
		}

		AIInterface::Update(p_time);
	}

	// 广播消息到座位列表
	void AIMaJiangChannelBaseInterface::BroadcastPacketSeat(WorldPacket * packet)
	{
		TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		{
			if ((*itSeat)->player.isNull() == false)
			{
				SendProtocolToPlayer(packet, *itSeat);
			}
		}
	}

	// 广播消息到观战列表（有些信息观战的不能看，所以要单独处理）
	void AIMaJiangChannelBaseInterface::BroadcastPacketWatch(WorldPacket * packet)
	{
		std::map<uint32, MJBaseTablePlayer >::iterator iter = m_mapWatchPlayers.begin();
		for (; iter != m_mapWatchPlayers.end(); ++iter)
		{
			if ((*iter).second.player.isNull() == false)
			{
				SendProtocolToPlayer(packet, (*iter).second);
			}
		}
	}

	// 广播消息到所有玩家列表
	void AIMaJiangChannelBaseInterface::BroadcastPacket(WorldPacket * packet, bool isLock)
	{
		BroadcastPacketSeat(packet);
		BroadcastPacketWatch(packet);
	}

	void AIMaJiangChannelBaseInterface::Broadcast(WorldPacket * packet, uint32 serial)
	{
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
			{
				if (serial == 0 || pTp->player._handle != serial)
				{
					SendProtocolToPlayer(packet, i);
				}
			}
		}
	}

	// 进入战场
	bool AIMaJiangChannelBaseInterface::JoinChannel(CharPtr & pChr, bool bSendPacket)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::JoinChannel", "JoinChannel?");
		MJBaseTablePlayer * pPlayer = GetTablePlayer(pChr->getHandle());

		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::JoinChannel", "JoinChannel");
		bool bJoinOk = false;
		if (IsGameStart(false) == false)
		{//游戏未开始
			WGS_MJCHANNEL_LOCK;
			if (pPlayer == NULL)
			{
				if (m_GameLogic->IsAutoSeatDown())
				{//是否自动入座
					TablePlayerIter iter = m_vSeatPlayers.begin();
					for (; iter != m_vSeatPlayers.end(); ++iter)
					{
						if ((*iter)->player.isNull())
						{
							break;
						}
					}
					if (iter != m_vSeatPlayers.end())
					{
						m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::JoinChannel", "pos:%d", (*iter)->pos);

						PlayerSit(pChr, (*iter)->pos);
					}
					else
					{
						m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::JoinChannel", "iter == end m_vSeatPlayers:%d", m_vSeatPlayers.size());
						return false;
					}
				}
				else
				{
					m_mapWatchPlayers[pChr->getHandle()].player = pChr;
				}
				AICreatureBaseInterface * pCharInterface = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
				if (pCharInterface)
				{
					pCharInterface->SetChannel(m_Unit);
					TownPtr pTown = sTownMgr.load(m_Unit->getUInt32Field("town_id"));
					pCharInterface->SetTown((ResourceProxy)pTown);
				}
			}
			bJoinOk = true;
			if (pChr->isNPC())
			{//机器人自动准备
				MJBaseTablePlayer * pNpc = GetTablePlayer(pChr->getHandle());
				pNpc->playerJoinState = MJ_PlayerReadyStatus_Ready;
				pNpc->nAgreePlayerGame = enAgreeOrRefuse_Agree;
				pNpc->m_ui32CoinModeOverTime = 0;
			}

			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::JoinChannel", "bJoinOk:%d", bJoinOk);
		}
		else
		{//游戏已经开始
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::JoinChannel", "GameStart false pPlayer:%d", pPlayer);
			if (pPlayer == NULL)
			{//角色不在列表中
				if (false)
				{//支持观战
					m_mapWatchPlayers[pChr->getHandle()].player = pChr;
				}
				else
					return false;
			}
			else
			{//重新连接
				pPlayer->m_ui32ExitChannelTime = 0;
				ReturnRoom(pPlayer);
				return true;
			}
			bJoinOk = true;
		}

		if (bJoinOk && bSendPacket)
		{
			WGS_MJCHANNEL_LOCK;
			pPlayer = GetTablePlayer(pChr->getHandle());
			if (pPlayer)
			{
				stCenterBattlePlayerInfo myInfo = sCenterBattleMgr.GetPlayerInfo(m_btLog.cb_id, pChr->getHandle());
				uint32 pid = 0;
				UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
				if (!pUser.isNull())
				{
					pid = pUser->getUInt32Field("platform_id");
				}
				if (pid == m_nFzPid)
					pPlayer->bFZ = true;
				m_ui8Trustee[pPlayer->pos] = enPlayer_Normal;

				pPlayer->score = myInfo.winLose;
				Log.Debug("AIMaJiangChannelBaseInterface::JoinChannel", "m_btLog.club_id[%d]", m_btLog.club_id);
				if (m_btLog.club_id != 0)
				{
					pPlayer->ui32ClubId = m_btLog.club_id;
					Log.Debug("AIMaJiangChannelBaseInterface::JoinChannel", "chr[%d] club[%d]", pPlayer->ui32ClubId , m_btLog.club_id);
				}
				pPlayer->ui8PayMode = m_ui8PayMode;
				if (m_ui8PayMode == 3)
					pPlayer->m_ui32CoinModeOverTime = time(0);
			}

			SendTableBaseProtocol(pChr);
		}

		return true;
	}

	// 返回牌桌
	void AIMaJiangChannelBaseInterface::ReturnRoom(MJBaseTablePlayer * pTp)
	{
		if (pTp == NULL)
		{
			Log.Error("AIMaJiangChannelBaseInterface::ReturnRoom", "pTp == NULL ");
			return;
		}
		CharPtr pChr = sCharMgr.load(pTp->player._handle);
		WorldPacket packet; 
		m_ui8Trustee[pTp->pos] = enPlayer_Normal;
		if(m_bBaoJiao[pTp->pos] == true)
			m_ui8Trustee[pTp->pos] = enPlayer_AutoHuPai;
		SendTableBaseProtocol(pChr);

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (i != pTp->pos)
				if (sProtocolsMgr.CreateMJPlayerStatusPacket(&packet, i, m_ui8Trustee[i]))
					sGLMgr.SendProtocolsToChr(pChr, &packet);
		}

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (sProtocolsMgr.CreateMJMagicCardsListPacket(&packet, m_ui8MagicCardsList[i]))
				sGLMgr.SendProtocolsToChr(pChr, &packet);
		}


		SendHandCards(pTp->pos, enSendCardType_All, true);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (m_ui8HuaPaiList[i].size() == 0) continue;
			if (sProtocolsMgr.CreateMJPlayerHuaPaiListPacket(&packet, i, m_ui8HuaPaiList[i]))
			{
				sGLMgr.SendProtocolsToChr(pChr, &packet);
			}
		}
	
		//额外操作
		CustomOperateInRuturnRoom(pTp);

		if (m_GameLogic->AllowedTingList())
			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, m_vecPlayerTingPaiTiShi[pTp->pos]))
				SendProtocolToPlayer(&packet, pTp->pos);

		//及时输赢
		if (m_bShowConstantlyCale)
			if (sProtocolsMgr.CreateMJConstantlyCalePacket(&packet, m_vecPlayerConstantlyCaleList))
				SendProtocolToPlayer(&packet, pTp->pos);

		if (pTp->ui8ChooseColor && m_run_status != en_MJChannelState_ChooseQue)
		{
			std::vector<uint8>  temp;
			TablePlayerIter iter, ei = m_vSeatPlayers.end();
			for (iter = m_vSeatPlayers.begin(); iter != ei; ++iter)
			{
				temp.push_back((*iter)->ui8ChooseColor);
			}
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJXuanQueListPacket(&packet, temp,false))
				BroadcastPacket(&packet);
		}
		if (m_nGameModeFlag == enMJGameMode_SCMJ_XZDD)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				{
					MJBaseTablePlayer * pTp2 = GetTablePlayerByPos(i);

					if (pTp2 == NULL) continue;
					if (m_ChiHuRight[i].IsEmpty() == true )
					{//玩家没有胡牌信息
						continue;
					}
					std::vector<uint8 >   vecHandCard;
					m_GameLogic->SwitchToCardData(m_ui8UserCardIndex[i], vecHandCard);
					WorldPacket	packet;
					if (sProtocolsMgr.CreateMJOperateHuPacket(&packet,
						i,
						vecHandCard,
						m_WeaveItemArray[i],
						pTp2->m_ui8ChiHuCard,
						GetHuPaiFanXing(i),
						pTp2->m_ui8ProvidePos,
						pTp2->m_ui8HuType,
						GetHuPaiExData(i)))
						SendProtocolToPlayer(&packet, pTp->pos);
				}
			}
		}

		uint32 ui32NowTime = now();
		uint32 ui32LeftTime = 0;
		if (getStatusEndTimer() > ui32NowTime)
		{
			ui32LeftTime = getStatusEndTimer() - ui32NowTime;
		}
		switch (m_run_status)
		{
		case en_MJChannelState_ChooseBanker:
			ReturnChooseBanker(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_SendCards:
			ReturnSendCards(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_SwapCards:
			ReturnSwapCards(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_ChooseQue:
			ReturnChooseQue(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_GiveCard:
			ReturnGiveCard(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_CastCard:
			ReturnCastCard(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_OperatorCard:
			ReturnOperateCard(pTp, ui32LeftTime);
			break;
		case en_MJChannelState_Custom:
			RuturnCustom(pTp, _StateKey, ui32LeftTime);
			break;
		default:
			ReturnCustomStatus(pTp, ui32LeftTime);
			break;
		}
		if (m_bVoting)
		{
			// 通知玩家当前投票结果列表（客户端开启投票结果显示面板） 
			uint32 now_time = time(0);
			if (now_time > m_nVoteOverTime)
				now_time = 0;
			else
				now_time = m_nVoteOverTime - now_time;
			if (sProtocolsMgr.CreateVoteListPacket(&packet, m_mapVotePlayers, now_time))
				BroadcastPacket(&packet);
		}

	}

	bool AIMaJiangChannelBaseInterface::ExitChannel(CharPtr & pChr, bool bOffline, bool bLock)
	{


		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::ExitChannel", "pChr:%d", pChr->getHandle());
		WorldPacket packet;
		if (m_mapWatchPlayers.find(pChr->getHandle()) != m_mapWatchPlayers.end())
		{
			m_mapWatchPlayers.erase(m_mapWatchPlayers.find(pChr->getHandle()));
			if (sProtocolsMgr.CreateMJWatchListPacket(&packet, m_mapWatchPlayers))
				BroadcastPacket(&packet);
			return true;
		}
		else
		{
			if (GetTablePlayer(pChr->getHandle()) == NULL) return true;
		}
		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());

		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::ExitChannel", "m_nLoopId:%d", m_nLoopId);
		if (m_run_status == en_MJChannelState_SameIP)
		{
			AgreeOrRefusePlayGame(pChr, enAgreeOrRefuse_Refuse);
		}
		if (IsGameStart() || (pChr->getStatus() & CharacterStatusWar) == CharacterStatusWar)
		{
			if (m_bVoting)
			{
				//PlayerDealVoteLock(pChr, voteType_Agree);
			}
			pTp->m_ui32ExitChannelTime = time(0);


		}
		else
		{
			WGS_MJCHANNEL_LOCK;

			Log.Debug("AIMaJiangChannelBaseInterface::ExitChannel", "channel[%d] char[%d] m_nLoopId:%d ",m_Unit->getHandle(),pChr->getHandle(), m_nLoopId);
			pTp->playerJoinState = MJ_PlayerReadyStatus_Leave;
			if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, pTp))
				BroadcastPacket(&packet);

			AICreatureBaseInterface * pCharInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
			if (pCharInter)
			{
				pCharInter->SetChannelNull();
				pCharInter->SetTownNull();
				pChr->setStatus(CharacterStatusFree);
			}
			Log.Error("AIMaJiangChannelBaseInterface::ExitChannel", "cb_id[%d] handle[%d] ",m_btLog.cb_id,pChr->getHandle());
			sCenterBattleMgr.PlayerLeaveChannel(m_btLog.cb_id, pChr->getHandle());
			pTp->ExChannel();
			pTp->playerJoinState = MJ_PlayerReadyStatus_Join;
			pTp->player.setNull();
			/*if (m_mapWatchPlayers.find(pChr->getHandle()) != m_mapWatchPlayers.end())
			{
				m_mapWatchPlayers.erase(m_mapWatchPlayers.find(pChr->getHandle()));
				if (sProtocolsMgr.CreateMJWatchListPacket(&packet, m_mapWatchPlayers))
					BroadcastPacket(&packet);
			}*/
		}

		return true;
	}





	void AIMaJiangChannelBaseInterface::ReturnChooseBanker(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{

	}

	void AIMaJiangChannelBaseInterface::ReturnSendCards(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{

	}

	void AIMaJiangChannelBaseInterface::ReturnSwapCards(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{
		//换牌中
		if (pTp->vecSwapingCards.empty())
		{
			WorldPacket packet;
			std::vector<uint8> temp;
			for (uint8 i = 0; i < pTp->vecInitSwapingCards.size(); i++)
			{
				temp.push_back(pTp->vecInitSwapingCards[i]);
			}
			if (sProtocolsMgr.CreateMJSwapCardsNotifyPacket(&packet, temp, ui32LeftTime ))
				SendProtocolToPlayer(&packet, pTp->pos);
		}
		else
		{
			WorldPacket packet;
			std::vector<uint8> temp;
			for (uint8 i = 0; i < pTp->vecSwapingCards.size(); i++)
			{
				temp.push_back(pTp->vecSwapingCards[i]);
			}
			if (sProtocolsMgr.CreateMJSwapCardsResultPacket(&packet, temp,pTp->ui8SwapFrom))
				SendProtocolToPlayer(&packet, pTp->pos);
		}
		if (CheckAllPlayerSwapCards())
		{
			if (m_i8SwapCardsPosType == enMJSwapCardsPosType_Default)
			{
				WorldPacket packet;
				if (sProtocolsMgr.CreateMJChooseSwapPosNotifyPacket(&packet, m_ui8BankerPos, ui32LeftTime ))
					SendProtocolToPlayer(&packet, pTp->pos);
			}
		}
	}

	void AIMaJiangChannelBaseInterface::ReturnChooseQue(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{
		//选缺中
		if (pTp->ui8ChooseColor == 0)
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJXuanQueNotifyPacket(&packet, pTp->ui8InitColor, ui32LeftTime ))
				SendProtocolToPlayer(&packet, pTp->pos);
		}
		else
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJPlayerXuanQueResultPacket(&packet, pTp->ui8ChooseColor, 1))
				SendProtocolToPlayer(&packet, pTp->pos);
		}
	
	}

	void AIMaJiangChannelBaseInterface::ReturnGiveCard(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{
	}

	void AIMaJiangChannelBaseInterface::ReturnCastCard(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJCastCardNotify(&packet, m_ui8CurrentPos, ui32LeftTime ))
			SendProtocolToPlayer(&packet, pTp->pos);
		if (m_MPlayerTingCardList[pTp->pos].size() && m_MPlayerTingCardList[pTp->pos].begin()->second.size() && m_MPlayerTingCardList[pTp->pos].begin()->second.front() != 0)
		{
			CMD_OperateNotify OperateNotify;
			OperateNotify.m_MPlayerTingCardList = m_MPlayerTingCardList[pTp->pos];
			OperateNotify.ui8ActionMask = 0;
			OperateNotify.ui8ResumePos = m_ui8ProvidePos;
			OperateNotify.ui8ActionCard = 0;
			if (sProtocolsMgr.CreateMJOperateNotifyPacket(&packet, OperateNotify))
				SendProtocolToPlayer(&packet, pTp->pos);
		}


	}

	void AIMaJiangChannelBaseInterface::ReturnOperateCard(MJBaseTablePlayer * pTp, uint32 ui32LeftTime)
	{
		//操作阶段
		if (m_ui8UserAction[pTp->pos] != WIK_NULL && m_bResponse[pTp->pos] == false)
		{
			CMD_OperateNotify OperateNotify;
			OperateNotify.m_MPlayerTingCardList = m_MPlayerTingCardList[pTp->pos];
			OperateNotify.m_VPlayerChiCardList = m_VPlayerChiCardList[pTp->pos];
			OperateNotify.m_VPlayerPengCardList = m_VPlayerPengCardList[pTp->pos];
			OperateNotify.m_VPlayerGangCardList = m_VPlayerGangCardList[pTp->pos];
			OperateNotify.ui32LeftTime = ui32LeftTime;
			OperateNotify.ui8ActionCard = m_ui8ProvideCard;
			if (m_bOutCardTingList)
			{
				if ((m_ui8UserAction[pTp->pos] & WIK_LISTEN) != 0)
					m_ui8UserAction[pTp->pos] = m_ui8UserAction[pTp->pos] ^ WIK_LISTEN;
				if (m_ui8UserAction[pTp->pos])
				{
					OperateNotify.m_MPlayerTingCardList.clear();
				}
			}
			OperateNotify.ui8ActionMask = m_ui8UserAction[pTp->pos];
			OperateNotify.ui8ResumePos = m_ui8ProvidePos;
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOperateNotifyPacket(&packet, OperateNotify))
				SendProtocolToPlayer(&packet, pTp->pos);
		}
	}



	uint32 AIMaJiangChannelBaseInterface::GetMaxPlayerNum()
	{
		return m_nMaxPlayerNum;
	}

	// 检测玩家是否同意进行游戏
	bool AIMaJiangChannelBaseInterface::CheckAllPlayerAgreePlayGame()
	{
		uint8 player_num = 0;
		TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		{
			if ((*itSeat)->player.isNull())
				continue;
			CharPtr pChr = sCharMgr.load((*itSeat)->player._handle);
			++player_num;
			if (pChr->isNPC())
				continue;
			if ((*itSeat)->nAgreePlayerGame != enAgreeOrRefuse_Agree)
				return false;
		}

		if (player_num < m_nMaxPlayerNum)
			return false;

		return true;
	}

	// 同意或者拒绝开始游戏
	bool AIMaJiangChannelBaseInterface::AgreeOrRefusePlayGame(CharPtr & pChr, const uint8 & agree_mode)
	{
		WGS_MJCHANNEL_LOCK
			if (pChr.isNull() || (agree_mode != enAgreeOrRefuse_Agree && agree_mode != enAgreeOrRefuse_Refuse))
				return false;

		bool bInSeat = false;
		if (m_run_status == en_MJChannelState_SameIP)
		{
			uint8 ui8Count = 0;
			TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
			for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
			{
				if (pChr->getHandle() == (*itSeat)->player._handle)
				{
					bInSeat = true;
					// 有玩家拒绝
					if (agree_mode == enAgreeOrRefuse_Refuse)
					{
						(*itSeat)->m_ui8SameIPStatus = enSameIPStatus_Refuse;
					}
					// 有玩家拒绝
					if (agree_mode == enAgreeOrRefuse_Agree)
					{
						(*itSeat)->m_ui8SameIPStatus = enSameIPStatus_OK;
						Log.Debug("AIMaJiangChannelBaseInterface::AgreeOrRefusePlayGame", "(*itSeat):%d m_ui8SameIPStatus:%d", (*itSeat)->pos, (*itSeat)->m_ui8SameIPStatus);
					}
				}

				if ((*itSeat)->m_ui8SameIPStatus == enSameIPStatus_OK)
				{
					ui8Count++;
				}

			}
			if (agree_mode == enAgreeOrRefuse_Refuse)
			{
				Log.Debug("AIMaJiangChannelBaseInterface::AgreeOrRefusePlayGame", "enAgreeOrRefuse_Refuse");
				m_bThinkSameIP = false;
			}
			else if (ui8Count == m_nMaxPlayerNum)
			{
				Log.Debug("AIMaJiangChannelBaseInterface::AgreeOrRefusePlayGame", "ui8Count:%d", ui8Count);
				m_bThinkSameIP = false;
				m_bHaveSameIP = false;
			}
		}
		else if (m_nLoopId == 0)
		{
			TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
			for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
			{
				if (pChr->getHandle() == (*itSeat)->player._handle)
				{
					(*itSeat)->nAgreePlayerGame = agree_mode;
					(*itSeat)->playerJoinState = MJ_PlayerReadyStatus_Ready;
					bInSeat = true;
					WorldPacket packet;
					if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, *itSeat))
						BroadcastPacket(&packet);
				}

				// 有玩家拒绝
				if (agree_mode == enAgreeOrRefuse_Refuse)
					(*itSeat)->nAgreePlayerGame = enAgreeOrRefuse_None;
			}

			if (agree_mode == enAgreeOrRefuse_Refuse)
			{// 玩家拒绝，起立终止游戏开始
			//	PlayerStandUp(pChr);
			}
		}
		else
		{// 结算后不能拒绝 只能准备
			if (agree_mode != enAgreeOrRefuse_Agree)
				return false;

			// 只允许在结算和准备状态下让玩家进行装备
			if (m_run_status != en_MJChannelState_Prep && m_run_status != en_MJChannelState_GameOverCalc)
				return false;

			TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
			for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
			{
				if (pChr->getHandle() == (*itSeat)->player._handle)
				{
					if ((*itSeat)->nAgreePlayerGame)
						continue;

					(*itSeat)->nAgreePlayerGame = agree_mode;
					(*itSeat)->playerJoinState = MJ_PlayerReadyStatus_Ready;
					bInSeat = true;
					WorldPacket packet;
					if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, *itSeat))
						BroadcastPacket(&packet);
				}
			}
		}

		if (!bInSeat)
			return false;

		WorldPacket packet;
		if (sProtocolsMgr.CreateAgreeOrRefusePacket(&packet, agree_mode, pChr->getHandle()))
			BroadcastPacket(&packet);

		return true;
	}

	// 房主发起解散牌桌
	bool AIMaJiangChannelBaseInterface::DissolveChannel()
	{
		WGS_MJCHANNEL_LOCK;
		WGS_MJCHANNEL_VOTE_LOCK;
		Log.Debug("AIMaJiangChannelBaseInterface::DissolveChannel", "ChannelId:%d", m_Unit->getHandle());
		m_next_run_status = en_MJChannelState_GameOverCalc;
		m_run_status = en_MJChannelState_GameOverCalc;
		m_bDissolve = true;
		m_bVoting = false;
		//m_mapVotePlayers.clear();
		m_bGameOver = true;

		m_nDissolveReson = DissolveType_Homeowners;

		setStatusEndTimer(0);

		// 发送系统消息
		/*WorldPacket packet;
		if (sProtocolsMgr.CreateLocalMessagePacket(&packet, sMsg.getMessage("owner_dissolve_channel").c_str(), sMsg.getType("owner_dissolve_channel")))
		BroadcastPacket(&packet);*/
		return true;
	}

	//判断牌局是否结束
	bool AIMaJiangChannelBaseInterface::CheckCenterBattleOver()
	{
		// 判断结束轮次
		Log.Debug("AIMaJiangChannelBaseInterface::CheckCenterBattleOver", "m_ui8RoundMode:%d", m_ui8RoundMode);
	
		if (m_bGameOver)
		{
			m_next_run_status = en_MJChannelState_Close;

			// 调用棋牌圈接口结束组局
			m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));
			m_btLog.mode = m_nMode;
			sCenterBattleMgr.CenterBattleComplate(m_btLog.cb_id);
			return true;
		}
		if (m_ui8RoundMode == enRoundMode_JuShu)
		{
			if (m_nLimitLoop && m_nLoopId < m_nLimitLoop)
				return false;
		}
		else if (m_ui8RoundMode == enRoundMode_QuanShu)
		{
			if (m_nLimitRound && m_nRoundId < m_nLimitRound)
				return false;
		}
		else
		{
			Log.Error("AIMaJiangChannelBaseInterface::CheckCenterBattleOver", "m_ui8RoundMode:%d", m_ui8RoundMode);
			ASSERT(false);
		}

		// 判断结束时间
		if (m_nLimitTime && m_nLimitTime < time(0) - m_nCreateTime)
			return false;

		// 设置要切换的状态到结束状态
		if (m_ui8RoundMode == enRoundMode_JuShu)
		{
			if (m_nLoopId >= m_nLimitLoop)
			{// 轮数限制到
				m_nDissolveReson = DissolveType_Loop;
			}
			else
			{// 时间限制到
				m_nDissolveReson = DissolveType_Time;
			}
		}
		else if (m_ui8RoundMode == enRoundMode_QuanShu)
		{
			Log.Debug("AIMaJiangChannelBaseInterface::CheckCenterBattleOver", "m_nRoundId:%d m_nLimitRound:%d", m_nRoundId, m_nLimitRound);
			if ( m_nRoundId >= m_nLimitRound)
			{// 轮数限制到
				m_nDissolveReson = DissolveType_Loop;
			}
			else
			{// 时间限制到
				m_nDissolveReson = DissolveType_Time;
			}
		}
		
		if (m_ui8PayMode == 3)
		{
			return false;
		}
		m_next_run_status = en_MJChannelState_Close;

		// 调用棋牌圈接口结束组局
		m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));
		m_btLog.mode = m_nMode;
		sCenterBattleMgr.CenterBattleComplate(m_btLog.cb_id);
		if (m_bGameOver)
			return true;
		return true;
	}

	//让离线托管玩家站起
	void AIMaJiangChannelBaseInterface::StandUpPlayerGameOver()
	{
		bool isStandUp = false, isReReady = false;
		for (uint8 i = 0; i < m_nMaxPlayerNum; ++i)
		{
			uint32 pid = 0;
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp == NULL) continue;
			CharPtr pChr = sCharMgr.load(pTp->player._handle);
			if (pChr.isNull()) continue;
			WSSocketPtr socket = pChr->getSocket();
			if (pChr->isNPC() == false && (m_GameLogic->IsGameOverStandUp() || (m_GameLogic->IsTrusteeshipStandUp() && m_ui8Trustee[i] != enPlayer_Normal)))
			{
				isStandUp = true;

				PlayerStandUp(pChr, false);
			}
			if (pChr->isNPC() == false && m_GameLogic->IsGameOverReReady())
			{
				isReReady = true;
				pTp->nAgreePlayerGame = enAgreeOrRefuse_None;
				pTp->playerJoinState = MJ_PlayerReadyStatus_Join;

			}
			if (m_ui8PayMode == 3)
			{
				pChr->setStatus(CharacterStatusFree);
			}
			m_ui8Trustee[i] = enPlayer_Normal;
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, pTp))
				BroadcastPacket(&packet);
		}

		if (isStandUp)
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJWatchListPacket(&packet, m_mapWatchPlayers))
				BroadcastPacket(&packet);
		}
	}

	// =============================游戏逻辑部分==============================================
	// 选择玩家默认交换的牌
	// 思路：统计每门花色的牌张数，计算牌力值，单张1点，对子10，三张100点，4张1000点。最后取满足牌张数且战力最小的一个花色出来
	void AIMaJiangChannelBaseInterface::ChoosePlayerInitSwapCardsWithOneColor(uint8 nChangeCount)
	{
		// 不是必须换牌，不默认玩家换牌列表
		if (!nChangeCount)
			return;

		TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		{
			if ((*itSeat)->player.isNull())
				continue;
			CharPtr pChr = sCharMgr.load((*itSeat)->player._handle);
			uint8 use_color = 0;
			uint32 use_power = 0;
			std::map<uint32, std::vector<uint32> >  mapCards;
			for (uint8 i = 0; i < 27; i++)
			{
				uint8 CardData = m_GameLogic->SwitchToCardData(i);
				mapCards[m_GameLogic->GetCardColor(CardData)].push_back(m_ui8UserCardIndex[(*itSeat)->pos][i]);
			}
			std::map<uint32, std::vector<uint32> >::iterator iterStand;
			for (iterStand = mapCards.begin(); iterStand != mapCards.end(); ++iterStand)
			{
				uint8 color_cardCount = 0;
				uint32 cards_power = 0;
				for (uint32 i = 0; i < iterStand->second.size(); ++i)
				{
					uint8 card_num = iterStand->second[i];
					if (card_num > 0)
					{

						color_cardCount += card_num;
						// if (card_num == 1)
							// cards_power += 1;
						// else if (card_num == 2)
							// cards_power += 10;
						// else if (card_num == 3)
							// cards_power += 100;
						// else
							// cards_power += 1000;
							cards_power += card_num;
					}
				}

				if (color_cardCount >= nChangeCount)
				{
					if (!use_color)
					{
						use_color = iterStand->first;
						use_power = cards_power;
						if(use_power == nChangeCount)
							break;
					}
					else
					{
						if (use_power > cards_power)
							use_color = iterStand->first;
					}
				}
			}
			std::vector<uint8> vecCardsTemp;

			std::map<uint32, std::vector<uint32> >::iterator fitColor = mapCards.find(use_color);
			if (fitColor != mapCards.end())
			{
				for (uint32 i = 0; i < fitColor->second.size(); ++i)
				{
					if (fitColor->second[i] > 0)
					{
						for (uint32 j = 0; j < fitColor->second[i]; ++j)
						{
							if ((*itSeat)->vecInitSwapingCards.size() < nChangeCount)
							{
								(*itSeat)->vecInitSwapingCards.push_back(MAKE_CARD(use_color, i + 1));
								vecCardsTemp.push_back(MAKE_CARD(use_color, i + 1));
							}
							else
								break;
						}
					}
				}
			}
		// 通知玩家系统选择的默认要交换的牌
			WorldPacket packet;
			
			if (pChr->isNPC())
			{
				(*itSeat)->isSwap = true;
				(*itSeat)->vecSwapingCards = (*itSeat)->vecInitSwapingCards;
			}
			if (sProtocolsMgr.CreateMJSwapCardsNotifyPacket(&packet, vecCardsTemp, m_nSwapCardsWaitTimer))
				sGLMgr.SendProtocolsToChr(pChr, &packet);
		}

	}

	// 玩家换牌
	bool AIMaJiangChannelBaseInterface::PlayerChooseSwapCards(CharPtr & pChr, std::vector<uint16> cards)
	{
		WGS_MJCHANNEL_LOCK

		if (pChr.isNull())
			return false;

		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());
		if (!pTp)
			return false;

		if (pTp->isSwap)
			return false;

		std::vector<uint8> vecCardTemp;
		for (uint8 i = 0; i < cards.size(); i++)
		{
			uint8 ui8CardIndex = m_GameLogic->SwitchToCardIndex(cards[i]);
			if (m_ui8UserCardIndex[pTp->pos][ui8CardIndex] < 1)
				return false;
			vecCardTemp.push_back(cards[i]);
		}

		/*if (!pTp->cards.checkcards(cards))
			return false;*/

		pTp->isSwap = true;
		pTp->vecSwapingCards = cards;

		// 发送玩家提交交换牌成功
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJPlayerSwapCardsResultPacket(&packet, vecCardTemp, 1));
			SendProtocolToPlayer(&packet, pTp);
		return true;
	}

	void AIMaJiangChannelBaseInterface::AutoChooseSwapCards()
	{
		TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		{
			if ((*itSeat)->isSwap)
				continue;

			(*itSeat)->vecSwapingCards = (*itSeat)->vecInitSwapingCards;
			std::vector<uint8> vecCardTemp;
			for (uint8 i = 0; i < (*itSeat)->vecSwapingCards.size(); i++)
			{
				vecCardTemp.push_back((*itSeat)->vecSwapingCards[i]);
			}
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJPlayerSwapCardsResultPacket(&packet, vecCardTemp, 1));
			SendProtocolToPlayer(&packet, (*itSeat));
		}
	}

	// 处理玩家换牌
	void AIMaJiangChannelBaseInterface::DealPlayerSwapCards()
	{
		//std::vector<uint16> vCards;
		//TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		//for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		//{
		//	vCards.insert(vCards.end(), (*itSeat)->vecSwapingCards.begin(), (*itSeat)->vecSwapingCards.end());
		//}

		//// 根据配置的洗牌次数进行换牌列表的洗牌
		//for (uint8 i = 0; i < sXmlDataMgr.GetConfXMLValue("COMMON_MJ_WASHSWAPCARDS_COUNT"); ++i)
		//{
		//	uint8 index = RandomUInt(vCards.size() - 1);
		//	uint8 index2 = RandomUInt(vCards.size() - 1);

		//	uint16 tempCard = vCards[index];
		//	vCards[index2] = vCards[index];
		//	vCards[index] = tempCard;
		//}
		SwapCards();

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			std::vector<uint8> vecCardTemp;
			for (uint8 k = 0; k < pTp->vecSwapingCards.size(); k++)
			{
				m_ui8UserCardIndex[i][m_GameLogic->SwitchToCardIndex(pTp->vecSwapingCards[k])]--;
			}
			for (uint8 k = 0; k < pTp->vecSwapedCards.size(); k++)
			{
				m_ui8UserCardIndex[i][m_GameLogic->SwitchToCardIndex(pTp->vecSwapedCards[k])]++;
				vecCardTemp.push_back(pTp->vecSwapedCards[k]);
			}
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJSwapCardsResultPacket(&packet, vecCardTemp,pTp->ui8SwapFrom))
				SendProtocolToPlayer(&packet, pTp);
		}
		
	}

	// 检测是否所有玩家都已换牌
	bool AIMaJiangChannelBaseInterface::CheckAllPlayerSwapCards()
	{
		TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		{
			if (!(*itSeat)->isSwap)
				return false;
		}

		return true;
	}

	// 获得玩家对象
	MJBaseTablePlayer * AIMaJiangChannelBaseInterface::GetTablePlayer(const uint32 & char_id)
	{
		MJBaseTablePlayer *pTp = NULL;
		TablePlayerIter iter = m_vSeatPlayers.begin();
		for (; iter != m_vSeatPlayers.end(); ++iter)
		{
			if (!(*iter)->player.isNull() && (*iter)->player._handle == char_id)
			{
				pTp = (*iter);
				break;
			}
		}

		return pTp;
	}

	MJBaseTablePlayer * AIMaJiangChannelBaseInterface::GetTablePlayerByPos(const uint32 & pos_id)
	{
		MJBaseTablePlayer *pTp = NULL;
		TablePlayerIter iter = m_vSeatPlayers.begin();
		for (; iter != m_vSeatPlayers.end(); ++iter)
		{
			if (!(*iter)->player.isNull() && (*iter)->pos == pos_id)
			{
				pTp = (*iter);
				break;
			}
		}

		return pTp;
	}

	// 获得观战玩家对象
	MJBaseTablePlayer * AIMaJiangChannelBaseInterface::GetWatchPlayer(const uint32 & char_id)
	{
		MJBaseTablePlayer * temp = NULL;
		if (m_mapWatchPlayers.find(char_id) != m_mapWatchPlayers.end())
		{
			temp = &m_mapWatchPlayers[char_id];
		}
		return temp;
	}

	// =============================游戏逻辑部分==============================================

	// 检测组局开始
	bool AIMaJiangChannelBaseInterface::CheckGameStart()
	{
		Log.Debug("AIMaJiangChannelBaseInterface::CheckGameStart", "");
		std::vector<uint32> playing_chars;
		std::vector<uint32> del_chars;

		uint8 seat_player = 0;
		bool bHaveOffLine = false;

		// 检查离线玩家不开始游戏
		TablePlayerIter itPlayer, eiPlayer = m_vSeatPlayers.end();
		for (itPlayer = m_vSeatPlayers.begin(); itPlayer != eiPlayer; ++itPlayer)
		{
			if ((*itPlayer)->player.isNull())
				continue;

			++seat_player;

			CharPtr pChr = sCharMgr.getByHandle((*itPlayer)->player._handle);
			if (pChr.isNull())
				continue;

			if (pChr->getStatus() & CharacterStatusWar)
				continue;

			WSSocketPtr sockPtr = pChr->getSocket();
			if (sockPtr.isNull() && !pChr->isNPC())
			{// 没有进行游戏的玩家，离线踢出
				if (seat_player > 0)
					--seat_player;

				bHaveOffLine = true;
				//	(*itPlayer).Init();
			}
			if (m_btLog.club_id != 0 && !pChr->isNPC())
			{
				UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
				MJBaseTablePlayer * pTp = *itPlayer;

				uint32 pid = 0;
				if (pUser.isNull() == false)
				{
					pid = pUser->getUInt32Field("platform_id");
				}
				
				if (sCenterClubMemberMgr.IsPlayerInClub(m_btLog.club_id, pid) == false ||
					(m_nLimitLoop == 0 &&  sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id, pChr) <= m_nExit_coins))
				{
					uint8 reson = DissolveType_KickoutClub;
					if(sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id, pChr) <= m_nExit_coins)
						reson = DissolveType_NeedCoins;
					
					Log.Debug("AIMaJiangChannelBaseInterface::CheckGameStart", "club num : %d  exit coins : %d ",sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id, pChr),m_nExit_coins);
					
					AICreatureBaseInterface * pCharInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
					if (pCharInter)
					{
						pCharInter->SetChannelNull();
						pCharInter->SetTownNull();
						pChr->setStatus(CharacterStatusFree);
					}
					
					ExitChannel(pChr, false, false);
					WorldPacket packet;
					if (sProtocolsMgr.CreateDissolveChannelPacket(&packet, reson))
						sGLMgr.SendProtocolsToChr(pChr, &packet);
					bHaveOffLine = true;
				}
			}
			
		}

		// 固定人数开始
		if (seat_player < m_nStartPlayerNum)
			return false;

		WorldPacket packet;
		if (bHaveOffLine)
		{
			// if(sProtocolsMgr.CreateCBChairInfoPacket(&packet, m_vSeatPlayers))
				// BroadcastPacketCB(&packet);
			return false;
		}

		++m_nLoopId;

	/*	if (m_ui8BankerPos == INVALID_uint8)
			m_nRoundId = 1;
		else*/
		{
			/*if (m_ui8NextBankerPos == ((m_ui8DongFengSeat - 1 + m_nMaxPlayerNum) % m_nMaxPlayerNum))
				m_nRoundId++;*/
		}

		for (itPlayer = m_vSeatPlayers.begin(); itPlayer != eiPlayer; ++itPlayer)
		{
			if ((*itPlayer)->player.isNull())
				continue;

			// (*itPlayer).nAgreePlayerGame = enAgreeOrRefuse_None;
			playing_chars.push_back((*itPlayer)->player._handle);

			// 设置角色战斗状态
			CharPtr pChr = sCharMgr.load((*itPlayer)->player._handle);
			// UpdatePlayStatus(&(*itPlayer), en_PlayStatus_Start);
			pChr->setStatus(CharacterStatusWar);
			// (*itPlayer).isStartGame = true;							// 设置进行游戏

			if (pChr->isNPC())
				m_ui8Trustee[(*itPlayer)->pos] = enPlayer_Trusteeship;
		}

		m_btLog.loop_id = m_nLoopId;								// 记录当前轮次
		m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));		// 创建时间
		m_nWarPlayerNum = seat_player;								// 开始游戏的玩家数量

		// 棋牌圈牌桌相关信息
		Json::Value val;
		Json::Reader reader;
		reader.parse(m_strPlayJsonData, val);

		val["start_time"] = m_nGameStartTime;
		val["curr_loop"] = m_nLoopId;
		if (m_ui8RoundMode == enRoundMode_QuanShu)
		{
			val["curr_round"] = m_nRoundId;
		}
		Json::FastWriter w;
		m_strPlayJsonData = w.write(val);

		if (sProtocolsMgr.CreateCenterBattleInfoPacket(&packet, m_strPlayJsonData))
			BroadcastPacket(&packet);

		if (m_nLoopId == 1)
		{
			m_nGameStartTime = time(0);
			m_btLog.use_time = m_nGameStartTime;
		}

		// 更新棋牌圈玩家列表数据
		sCenterBattleMgr.StartNewLoop(m_btLog.cb_id, del_chars, playing_chars);
		Log.Debug("SSSAICenterChannelInterface::CheckGameStart", "channel[%u] cb_id[%u] loop_id[%u] game start!",
			m_Unit->getHandle(), m_btLog.cb_id, m_btLog.loop_id);
		return true;
	}

	//初始话玩家列表
	void AIMaJiangChannelBaseInterface::InitPlayerSeatList()
	{
		// 初始座位列表
		for (uint8 i = 0; i < m_nMaxPlayerNum; ++i)
		{
			MJBaseTablePlayer* tp = new MJBaseTablePlayer;

			//重要   从tableplayer获取手牌数据必须调用该方法
			tp->SetChannelInterface(this);

			tp->playerJoinState = MJ_PlayerReadyStatus_Join;
			tp->pos = i;

			m_vSeatPlayers.push_back(tp);
		}
	}

	//游戏是否开始
	bool AIMaJiangChannelBaseInterface::IsGameStart(bool bLock)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::IsGameStart", "IsGameStart m_run_status:%d", m_run_status);
		if (bLock)
		{
			WGS_MJCHANNEL_LOCK;
			return IsGameStart(false);
		}
		return (m_run_status != en_MJChannelState_Prep && m_run_status != en_MJChannelState_SameIP);
	}

	//通知牌桌状态
	void AIMaJiangChannelBaseInterface::SendTableStatus(const uint32 & serial, bool bReconnection)
	{
		CMD_GameStart GameStart;
		if (IsGameStart())
		{
			GameStart.ui8BankerPos = m_ui8BankerPos;
			GameStart.ui8DongFengSeat = m_ui8DongFengSeat;
			GameStart.ui8GameStatus = bReconnection ? enMJGaneStats_Reconnection : enMJGaneStats_Gameing;
			GameStart.ui8LeftCardCount = m_uint8MaxCardNum;
			GameStart.vecDicePoint = m_dice;
			GameStart.ui8SendCardPos = (m_dice[0] + m_dice[1]) % m_nMaxPlayerNum;
			GameStart.ui8FirstDispatchCardPos = (m_dice[2] + m_dice[3]);
		}
		else
		{
			GameStart.ui8BankerPos = m_ui8BankerPos;
			GameStart.ui8DongFengSeat = m_ui8DongFengSeat;
			GameStart.ui8GameStatus = enMJGaneStats_Pre;
			GameStart.ui8LeftCardCount = 0;
			GameStart.vecDicePoint = m_dice;
			GameStart.ui8SendCardPos = (m_dice[0] + m_dice[1]) % m_nMaxPlayerNum;
			GameStart.ui8FirstDispatchCardPos = (m_dice[2] + m_dice[3]);

		}
		WorldPacket packet;

		if (sProtocolsMgr.CreateMJGameStatusPacket(&packet, GameStart))
		{
			if (serial == 0)
				BroadcastPacket(&packet);
			else
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::SendTableStatus", "SendTableStatus");
				SendProtocolToPlayer(&packet, GetTablePlayer(serial));
			}
		}
	}

	//玩家加入牌桌需要发的基本协议
	void AIMaJiangChannelBaseInterface::SendTableBaseProtocol(CharPtr & pChr)
	{
		WorldPacket packet;
		if (m_nCB_id)
		{//如果在棋牌圈
			if (sProtocolsMgr.CreateCenterBattleInfoPacket(&packet, m_strPlayJsonData))
			{
				sGLMgr.SendProtocolsToChr(pChr, &packet);
			}
		}
		Log.Debug("AIMaJiangChannelBaseInterface::SendTableBaseProtocol", "m_vSeatPlayers.size:%d", m_vSeatPlayers.size());
		TablePlayerIter iter = m_vSeatPlayers.begin(), iterP = m_vSeatPlayers.begin();
		for (; iter != m_vSeatPlayers.end(); ++iter)
		{//先通知玩家自己

			Log.Debug("AIMaJiangChannelBaseInterface::SendTableBaseProtocol", "id1:%d  chr[%d]", (*iter)->player._handle, pChr->getHandle());
			if ((*iter)->player._handle == pChr->getHandle())
			{
				if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, *iter))
					sGLMgr.SendProtocolsToChr(pChr, &packet);
				iterP = iter;
				break;
			}

		}
		for (iter = m_vSeatPlayers.begin(); iter != m_vSeatPlayers.end(); ++iter)
		{//通知玩家玩家列表
			if ((*iter)->player.isNull() == false && iterP != iter)
			{
				if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, *iter))
					sGLMgr.SendProtocolsToChr(pChr, &packet);
			}
		}
		if (iterP != m_vSeatPlayers.end())
		{//更新其他玩家的玩家列表
			for (iter = m_vSeatPlayers.begin(); iter != m_vSeatPlayers.end(); ++iter)
			{
				if ((*iter)->player.isNull() == false && iter != iterP)
				{
					if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, *iterP))
						SendProtocolToPlayer(&packet, *iter);
				}
			}
		}
		if (sProtocolsMgr.CreateMJWatchListPacket(&packet, m_mapWatchPlayers))
		{//更新观战列表
			BroadcastPacket(&packet);
		}

		SendTableStatus(pChr->getHandle(), IsGameStart());

		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());

		if(pTp)
			SendPlayerStatus(pTp->pos, m_ui8Trustee[pTp->pos]);

	}

	// 玩家入座
	bool AIMaJiangChannelBaseInterface::PlayerSit(CharPtr & pChr, const uint32 & seat_id, bool bLock)
	{
		if (pChr.isNull())
			return false;

		// 座位超出范围
		if (seat_id > m_vSeatPlayers.size())
			return false;

		if (bLock)
		{
			WGS_MJCHANNEL_LOCK;
			return PlayerSit(pChr, seat_id, false);
		}

		TablePlayerIter iter, ei = m_vSeatPlayers.end();
		for (iter = m_vSeatPlayers.begin(); iter != ei; iter++)
		{
			if ((*iter)->pos == seat_id && (*iter)->player.isNull())
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::PlayerSit", "pChr:%d seat:%d", pChr->getHandle(), seat_id);
				(*iter)->player = pChr;
				if (m_mapWatchPlayers.find(pChr->getHandle()) != m_mapWatchPlayers.end())
				{
					m_mapWatchPlayers.erase(m_mapWatchPlayers.find(pChr->getHandle()));
				}
				return true;
			}
		}


		return false;
	}

	// 玩家起立
	bool AIMaJiangChannelBaseInterface::PlayerStandUp(CharPtr & pChr, bool bLock)
	{
		if (bLock)
		{
			WGS_MJCHANNEL_LOCK;
			return PlayerStandUp(pChr, false);
		}
		if (pChr.isNull())
			return false;
		Log.Debug("AIMaJiangChannelBaseInterface::PlayerStandUp", "pChr:%d", pChr->getHandle());
		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());

		if (pTp == NULL) return false;

		m_mapWatchPlayers[pTp->player._handle].player = pTp->player;

		pTp->playerJoinState = MJ_PlayerReadyStatus_Leave;
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, pTp))
			BroadcastPacket(&packet);
		pTp->player.setNull();
		if (sProtocolsMgr.CreateMJWatchListPacket(&packet, m_mapWatchPlayers))
			BroadcastPacket(&packet);
		return false;
	}

	// 玩家发起投票
	bool AIMaJiangChannelBaseInterface::PlayerSendVote(CharPtr & pChr)
	{
		uint8 result = enZYMJSendVoteState_OK;
		WGS_MJCHANNEL_LOCK;
		{
			if (pChr.isNull())
				return false;

			if (m_run_status == en_MJChannelState_Close || m_nLoopId == 0)
				return false;

			uint32 time_now = time(0);
			do
			{
				if (m_bVoting)
				{// 正在投票中
					result = enZYMJSendVoteState_INVOTE;
					break;
				}

				bool bFind = false;
				TablePlayerIter iter, ei = m_vSeatPlayers.end();
				for (iter = m_vSeatPlayers.begin(); iter != ei; ++iter)
				{
					if ((*iter)->player.isNull())
						continue;

					if ((*iter)->player._handle == pChr->getHandle())
					{
						bFind = true;
						break;
					}
				}

				std::map<uint32, MJBaseTablePlayer>::iterator fitFree = m_mapWatchPlayers.find(pChr->getHandle());
				if (fitFree != m_mapWatchPlayers.end())
				{
					bFind = true;
					break;
				}

				if (!bFind)
				{// 错误的玩家
					result = enZYMJSendVoteState_Default;
					break;
				}

			} while (0);
			WorldPacket packet;

			Log.Debug("AIMaJiangChannelBaseInterface::PlayerSendVote", "channel[%u] char[%u] result[%u]", m_Unit->getHandle(), pChr->getHandle(), result);

			if (result == enZYMJSendVoteState_OK)
			{
				m_bVoting = true;
				TablePlayerIter iter, ei = m_vSeatPlayers.end();
				for (iter = m_vSeatPlayers.begin(); iter != ei; ++iter)
				{
					if ((*iter)->player.isNull())
						continue;

					uint32 char_id = (*iter)->player._handle;

					stVotePlayer stVP;
					stVP.char_id = char_id;
					if (char_id == pChr->getHandle())
					{// 发起投票的玩家直接算同意
						stVP.vote_status = voteType_Agree;
					}

					m_mapVotePlayers.insert(std::make_pair(char_id, stVP));
				}

				std::map<uint32, MJBaseTablePlayer>::iterator itFree, eiFree = m_mapWatchPlayers.end();
				for (itFree = m_mapWatchPlayers.begin(); itFree != eiFree; ++itFree)
				{
					stVotePlayer stVP;
					stVP.char_id = itFree->first;
					if (itFree->first == pChr->getHandle())
					{// 发起投票的玩家直接算同意
						stVP.vote_status = voteType_Agree;
					}

					m_mapVotePlayers.insert(std::make_pair(itFree->first, stVP));
				}
				/*	m_run_status = en_MJChannelState_Vote;
					m_next_run_status = en_MJChannelState_Vote;*/
				uint32 _time = now();
				if (getStatusEndTimer() > _time)
				{
					m_ui32LogStatusTime = getStatusEndTimer() - _time;
				}
				else
					m_ui32LogStatusTime = 0;
				Log.Debug("AIMaJiangChannelBaseInterface::PlayerSendVote", "VOTE_WAIT_TIME:%d", m_GameLogic->GetChannelTime("VOTE_WAIT_TIME"));
				m_nVoteOverTime = time_now + (m_GameLogic->GetChannelTime("VOTE_WAIT_TIME") == 0 ? sXmlDataMgr.GetConfXMLValue("VOTE_WAIT_TIME") : m_GameLogic->GetChannelTime("VOTE_WAIT_TIME"));

				Log.Debug("AIMaJiangChannelBaseInterface::PlayerSendVote", "channel[%u] char[%u] m_nVoteOverTime[%u] vote size[%u]",
					m_Unit->getHandle(), pChr->getHandle(), m_nVoteOverTime, m_mapVotePlayers.size());

				// 群发发起投票结果
				if (sProtocolsMgr.CreateSendVotePacket(&packet, pChr->getHandle(), result))
					BroadcastPacket(&packet);
				// 通知玩家当前投票结果列表（客户端开启投票结果显示面板）
				if (sProtocolsMgr.CreateVoteListPacket(&packet, m_mapVotePlayers, m_nVoteOverTime - time_now))
					BroadcastPacket(&packet);
			}
			else
			{
				// 单独发送失败结果
				if (sProtocolsMgr.CreateSendVotePacket(&packet, pChr->getHandle(), result))
					sGLMgr.SendProtocolsToChr(pChr, &packet);
			}
		}

		if (result == enZYMJSendVoteState_OK)
		{
			//	WGS_MJCHANNEL_VOTE_LOCK;
			//	WGS_MJCHANNEL_LOCK;
			while (m_bVoting)
			{
				if (m_nVoteOverTime)
				{// 检测投票自动逻辑
					if ((time(0) >= m_nVoteOverTime) && m_bVoting)
					{
						std::map<uint32, stVotePlayer> tempVotePlayers;

						{
							//		WGS_MJCHANNEL_LOCK;
							WGS_MJCHANNEL_VOTE_LOCK;
							tempVotePlayers = m_mapVotePlayers;
						}
						std::map<uint32, stVotePlayer>::iterator itVote, eiVote = tempVotePlayers.end();
						for (itVote = tempVotePlayers.begin(); itVote != eiVote; ++itVote)
						{
							if (itVote->second.vote_status)
								continue;

							CharPtr pChr = sCharMgr.load(itVote->first);
							PlayerDealVoteLock(pChr, voteType_Agree);
						}
					}
				}
			}
			setStatusEndTimer(m_ui32LogStatusTime);
		}
		return true;
	}

	// 玩家处理投票
	bool AIMaJiangChannelBaseInterface::PlayerDealVote(CharPtr & pChr, const uint8 & mode)
	{
		//	WGS_MJCHANNEL_LOCK;
		return PlayerDealVoteLock(pChr, mode);

	}

	// 玩家处理投票
	bool AIMaJiangChannelBaseInterface::PlayerDealVoteLock(CharPtr & pChr, const uint8 & mode)
	{
		Log.Debug("AIMaJiangChannelBaseInterface::PlayerDealVote", "channel[%u] char[%u] mode[%u] 1", m_Unit->getHandle(), pChr->getHandle(), mode);
		WGS_MJCHANNEL_VOTE_LOCK;
		if (pChr.isNull())
			return false;

		Log.Debug("AIMaJiangChannelBaseInterface::PlayerDealVote", "channel[%u] char[%u] mode[%u] 2", m_Unit->getHandle(), pChr->getHandle(), mode);
		if (mode != voteType_Agree && mode != voteType_Refuse)
			return false;

		std::map<uint32, stVotePlayer>::iterator fitVote;
		uint8 result = enVoteResult_Sucess;
		do
		{
			if (!m_bVoting)
			{// 未在投票进行中
				result = enVoteResult_NotInVoting;
				break;
			}

			fitVote = m_mapVotePlayers.find(pChr->getHandle());
			if (fitVote == m_mapVotePlayers.end())
			{// 未找到玩家，还没有开始投票
				result = enVoteResult_NotInVoting;
				break;
			}

			if (fitVote->second.vote_status != voteType_NoChoice)
			{// 玩家已经有过选择
				result = enVoteResult_Voted;
				break;
			}

		} while (0);

		WorldPacket packet;
		if (result == 1)
		{
			// 设置玩家投票结果
			fitVote->second.vote_status = mode;

			// 更新投票列表
			uint32 time_now = time(0);
			uint32 left_time = m_nVoteOverTime >= time_now ? m_nVoteOverTime - time_now : 0;
			uint8 vote_player = m_nWarPlayerNum;
			if (mode == voteType_Refuse)
			{// 拒绝
				uint8 refuse_count = 0;
				std::vector<uint32> vRefuseCharsID;

				std::map<uint32, stVotePlayer>::iterator itVote, eiVote = m_mapVotePlayers.end();
				for (itVote = m_mapVotePlayers.begin(); itVote != eiVote; ++itVote)
				{
					if (itVote->second.vote_status == voteType_Refuse)
					{
						vRefuseCharsID.push_back(itVote->first);
						++refuse_count;
					}
				}

				if (sProtocolsMgr.CreateVoteListPacket(&packet, m_mapVotePlayers, left_time, enVoteFinalResult_Continue))
					BroadcastPacket(&packet);

				// 重置玩家选择结果
				for (itVote = m_mapVotePlayers.begin(); itVote != m_mapVotePlayers.end(); ++itVote)
				{
					itVote->second.vote_status = voteType_NoChoice;
				}

				// 结束投票
				m_bVoting = false;
				m_mapVotePlayers.clear();
				m_nVoteOverTime = 0;
				Log.Debug("AIMaJiangChannelBaseInterface::PlayerDealVote", "channel[%u] char[%u] refuse!", m_Unit->getHandle(), pChr->getHandle());
			}
			else
			{// 同意
				uint8 agree_count = 0;
				std::vector<uint32> vAgreeCharsID;

				std::map<uint32, stVotePlayer>::iterator itVote, eiVote = m_mapVotePlayers.end();
				for (itVote = m_mapVotePlayers.begin(); itVote != eiVote; ++itVote)
				{
					if (itVote->second.vote_status == voteType_Agree)
					{
						agree_count++;
						vAgreeCharsID.push_back(itVote->first);
					}
				}

				// 全部同意的版本
				if (vote_player != agree_count)
				{
					if (sProtocolsMgr.CreateVoteListPacket(&packet, m_mapVotePlayers, left_time, enVoteFinalResult_Voting))
						BroadcastPacket(&packet);
					return false;
				}

				if (sProtocolsMgr.CreateVoteListPacket(&packet, m_mapVotePlayers, left_time, enVoteFinalResult_Dissolve))
					BroadcastPacket(&packet);

				m_bVoting = false;
				m_mapVotePlayers.clear();

				m_bGameOver = true;
				m_bDissolve = true;
				m_nVoteOverTime = 0;
				m_nDissolveReson = DissolveType_Vote;
				m_next_run_status = en_MJChannelState_GameOverCalc;
				//	m_run_status = en_MJChannelState_GameOverCalc;

				Log.Debug("AIMaJiangChannelBaseInterface::PlayerDealVote", "channel[%u] char[%u] all agree!", m_Unit->getHandle(), pChr->getHandle());
			}
		}
		else
		{
			return false;
		}

		return true;
	}

	// 将所有玩家清出房间
	void AIMaJiangChannelBaseInterface::AllPlayersLeaveRoom()
	{
		WorldPacket packet;

		TablePlayerIter itSeat, eiSeat = m_vSeatPlayers.end();
		for (itSeat = m_vSeatPlayers.begin(); itSeat != eiSeat; ++itSeat)
		{
			if ((*itSeat)->player.isNull())
				continue;

			CharPtr pChr = sCharMgr.load((*itSeat)->player._handle);
			if (pChr.isNull())
				continue;

			AICreatureBaseInterface * pChrAIInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
			if (!pChrAIInter)
				continue;

			pChr->setStatus(CharacterStatusFree);

			//离开房间
			pChrAIInter->SetTownNull();
			pChrAIInter->SetChannelNull();
		}

		std::map<uint32, MJBaseTablePlayer>::iterator itFree, eiFree = m_mapWatchPlayers.end();
		for (itFree = m_mapWatchPlayers.begin(); itFree != eiFree; ++itFree)
		{
			if (itFree->second.player.isNull())
				continue;

			CharPtr pChr = sCharMgr.load(itFree->first);
			if (pChr.isNull())
				continue;

			AICreatureBaseInterface * pChrAIInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
			if (!pChrAIInter)
				continue;

			pChr->setStatus(CharacterStatusFree);

			//离开房间
			pChrAIInter->SetTownNull();
			pChrAIInter->SetChannelNull();
		}
	}

	// 初始状态
	HSMState AIMaJiangChannelBaseInterface::battle_init(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		return HSM_TRAN(&AIMaJiangChannelBaseInterface::battle_prep);
	}

	// 准备状态
	HSMState AIMaJiangChannelBaseInterface::battle_prep(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_Prep);
			me->setChannelBattlePrep();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattlePrepUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 准备Init
	void AIMaJiangChannelBaseInterface::setChannelBattlePrep(void)
	{
		SendTableStatus(0);
		m_status_endtimer = now() + 5000;	// 如果要自动准备的，时间到了还没开始就自动准备
		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattlePrep", "channel[%u] cb_id[%u] prep!", m_Unit->getHandle(), m_btLog.cb_id);
		if (m_ui8PayMode == 3)
		{// 不准备超时时间设置
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL) continue;
				pTp->m_ui32CoinModeOverTime = time(0);

			}
		}

		if (m_ui8PayMode == 3)
		{//检测钱儿够不够
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL) continue;
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr.isNull()) continue;
				if (pChr->isNPC()) continue;
				Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "chr[%d] money:%d m_nExit_coins:%d", pChr->getHandle(), sGLMgr.GetItemNum(pChr, ItemModel_Coins), m_nExit_coins);
				if (m_btLog.club_id == 0)
				{
					if (sGLMgr.GetItemNum(pChr, ItemModel_Coins) < m_nExit_coins)
					{
						AICreatureBaseInterface * pCharInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
						if (pCharInter)
						{
							pCharInter->SetChannelNull();
							pCharInter->SetTownNull();
							pChr->setStatus(CharacterStatusFree);
						}

						ExitChannel(pChr, false, false);
						WorldPacket packet;
						if (sProtocolsMgr.CreateDissolveChannelPacket(&packet, DissolveType_NeedCoins))
							sGLMgr.SendProtocolsToChr(pChr, &packet);
					}

				}
				else
				{
					UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
					uint32 pid = 0;
					if (pUser.isNull() == false)
					{
						pid = pUser->getUInt32Field("platform_id");
					}
					uint32 reson = 0;
					if (sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id, pChr) <= m_nExit_coins)
					{// 俱乐部分数不足
						reson = DissolveType_NeedCoins;
					}
					else if (sCenterClubMemberMgr.IsPlayerInClub(m_btLog.club_id, pid) == false)
					{// 被踢出俱乐部了
						reson = DissolveType_KickoutClub;
					}
					else if (pTp->m_bClearClubScore)
					{// 俱乐部被退分
						reson = DissolveType_ClubManagerClearScore;
					}

					if (reson != 0)
					{
						AICreatureBaseInterface * pCharInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
						if (pCharInter)
						{
							pCharInter->SetChannelNull();
							pCharInter->SetTownNull();
							pChr->setStatus(CharacterStatusFree);
						}

						ExitChannel(pChr, false, false);
						WorldPacket packet;
						if (sProtocolsMgr.CreateDissolveChannelPacket(&packet, reson))
							sGLMgr.SendProtocolsToChr(pChr, &packet);
					}
				}

			}
		}

		m_nTimeoutTimer = m_GameLogic->GetChannelTime("ChannelOverTime");
		m_nTingQianChangTimer = time(0);
	}

	// 准备Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattlePrepUpdate(void)
	{
		if (m_next_run_status == en_MJChannelState_GameOverCalc || m_run_status == en_MJChannelState_GameOverCalc)
		{
			return ChangeChannelState(m_next_run_status);
		}

		if (m_ui8PayMode == 3)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL) continue;
				if (pTp->nAgreePlayerGame == enAgreeOrRefuse_None && pTp->m_ui32CoinModeOverTime != 0 && time(0) - pTp->m_ui32CoinModeOverTime > m_GameLogic->GetChannelTime("CoinModeOverTime"))
				{
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattlePrepUpdate", "");
					CharPtr pChr = sCharMgr.load(pTp->player._handle);
					ExitChannel(pChr, false, false);
					WorldPacket packet;
					if (sProtocolsMgr.CreateDissolveChannelPacket(&packet, DissolveType_NotReady))
						sGLMgr.SendProtocolsToChr(pChr, &packet);
				}
			}

		}


		if (!CheckAllPlayerAgreePlayGame())
		{// 检查是不是所有玩家已经装备
			return 0;
		}

		if (m_bSameIPCheck && m_bHaveSameIP)
		{
			Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattlePrepUpdate", "SameIP channel[%u] cb_id[%u]", m_Unit->getHandle(), m_btLog.cb_id);
			return ChangeChannelState(en_MJChannelState_SameIP);
		}
		if (CheckGameStart())
		{// 游戏开始
			Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattlePrepUpdate", "channel[%u] cb_id[%u]", m_Unit->getHandle(), m_btLog.cb_id);
			m_nTimeoutTimer = 0;
			if (m_ui8PayMode == 3 && m_bDealDuiJuFei)
			{
				DealDuiJuFei();
				//m_bDealDuiJuFei = false;
			}
			return ChangeChannelState(en_MJChannelState_ChooseBanker);
			m_bHaveSameIP = false;

		}
		//	Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattlePrepUpdate", "m_next_run_status:%d  m_run_status:%d", m_next_run_status, m_run_status);


		return 0;
	}

	// 定庄状态
	HSMState AIMaJiangChannelBaseInterface::battle_choosebanker(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_ChooseBanker);
			me->setChannelBattleChooseBanker();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleChooseBankerUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 定庄Init
	void AIMaJiangChannelBaseInterface::setChannelBattleChooseBanker(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_bVoting)
			return;
		// 丢骰子
		for (uint8 i = 0; i < 4; i++)
		{
			m_dice[i] = RandomUInt(1, 6);
		}
		if (m_ui8BankerPos == INVALID_uint8)
		{//随机生成庄家
			MakeRandBanker();
		}
		else if (m_ui8NextBankerPos != INVALID_uint8)
		{
			m_vSeatPlayers[m_ui8BankerPos]->isBanker = false;
			m_ui8BankerPos = m_ui8NextBankerPos;
		}
		


		//测试
		TestHandCards();
		if (m_ui8DongFengSeat == INVALID_uint8)
			m_ui8DongFengSeat = m_ui8BankerPos;
		m_ui8CurrentPos = m_ui8BankerPos;
		m_vSeatPlayers[m_ui8BankerPos]->isBanker = true;

		
		//牌桌状态
		SendTableStatus(0);

		// 通知玩家庄家产生
		// WorldPacket packet;
		// if (sProtocolsMgr.CreateBringBankerPacket(&packet, m_dice, m_ui8BankerUser))
			// Broadcast(&packet);
		m_status_endtimer = now() + m_nChooseBankerWaitTimer;
		m_next_run_status = en_MJChannelState_SendCards;
		LogGameStart();

		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleChooseBanker", "channel[%u] cb_id[%u] m_ui8BankerPos:%d!", m_Unit->getHandle(), m_btLog.cb_id, m_ui8BankerPos);
	}

	// 定庄Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleChooseBankerUpdate(void)
	{
		if (m_status_endtimer <= now())
		{// 定庄时间到，发牌
			return ChangeChannelState(m_next_run_status);
		}

		return 0;
	}

	// 发牌状态
	HSMState AIMaJiangChannelBaseInterface::battle_sendcards(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_SendCards);
			me->setChannelBattleSendCards();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleSendCardsUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 发牌Init
	void AIMaJiangChannelBaseInterface::setChannelBattleSendCards(void)
	{
		WGS_MJCHANNEL_LOCK;
	
		uint32 point = m_dice[0] + m_dice[1];
		switch (point)
		{
		case 5:
		case 9:

			m_curStartPos = m_ui8BankerPos;
			m_ui8CurrentPos = m_ui8BankerPos;
			break;
		case 2:
		case 6:
		case 10:
			m_curStartPos = (m_ui8BankerPos + 1) % 4;
			m_ui8CurrentPos = m_ui8BankerPos;
			break;
		case 3:
		case 7:
		case 11:
			m_curStartPos = (m_ui8BankerPos + 2) % 4;
			m_ui8CurrentPos = m_ui8BankerPos;
			break;
		case 4:
		case 8:
		case 12:
			m_curStartPos = (m_ui8BankerPos + 3) % 4;
			m_ui8CurrentPos = m_ui8BankerPos;
			break;
		}



		// 指定发牌位置
		// WorldPacket packet;
		// if (sProtocolsMgr.CreateStartGiveCardPosPacket(&packet, m_dice, m_curStartPos))
			// BroadcastPacket(&packet);
		if (m_ui8DongFengSeat == INVALID_uint8)
			m_ui8DongFengSeat = m_ui8BankerPos;




		SendMagicCardList();
		// 发牌
		DistributeInitalHandCards(m_ui8MaxHandCount - 1);

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			SendHandCards(i, enSendCardType_All);
		}
		LogPlayerHandCars();
		//及时输赢
		WorldPacket packet;
		if (m_bShowConstantlyCale)
			if (sProtocolsMgr.CreateMJConstantlyCalePacket(&packet, m_vecPlayerConstantlyCaleList))
				BroadcastPacket(&packet);
		m_status_endtimer = now() + m_nSendInitalCardsWaitTimer;
	}

	// 发牌Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleSendCardsUpdate(void)
	{
		if (m_status_endtimer <= now())
		{
			//if ((m_nGameModeFlag & enPlayerMode_Swap) != 0)
			//{// 有换牌玩法，切换到换牌流程
			//	return ChangeChannelState(en_MJChannelState_SwapCards);
			//}
			//else if ((m_nGameModeFlag & enPlayerMode_Que) != 0)
			//{// 有定缺玩法，切换到定缺流程
			//	return ChangeChannelState(en_MJChannelState_ChooseQue);
			//}
			//else
			{// 普通玩法，直接摸牌
				return ChangeChannelState(en_MJChannelState_SendCardsBuPai);
			}
		}

		return 0;
	}

	// 换牌状态
	HSMState AIMaJiangChannelBaseInterface::battle_swapcards(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_SwapCards);
			me->setChannelBattleSwapCards();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleSwapCardsUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 换牌Init
	void AIMaJiangChannelBaseInterface::setChannelBattleSwapCards(void)
	{
		// 发包通知玩家开始换牌

		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleSwapCards", "channel[%u] cb_id[%u] 1", m_Unit->getHandle(), m_btLog.cb_id);
		// 初始玩家默认交换的牌
		ChoosePlayerInitSwapCardsWithOneColor(3);

		m_status_endtimer = now() + m_nSwapCardsWaitTimer;
		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleSwapCards", "channel[%u] cb_id[%u] 2", m_Unit->getHandle(), m_btLog.cb_id);
	}

	// 换牌Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleSwapCardsUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_bVoting)
			return ChangeChannelState(m_next_run_status);
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return ChangeChannelState(m_next_run_status);
		// 如果玩家都已换牌，直接交换牌，还给玩家，切换下个状态
		if (CheckAllPlayerSwapCards())
		{
			// 处理玩家交换的牌
			if (m_i8SwapCardsPosType == -1)
			{
				m_i8SwapCardsPosType = enMJSwapCardsPosType_Default;
				WorldPacket packet;
				if (sProtocolsMgr.CreateMJChooseSwapPosNotifyPacket(&packet, m_ui8BankerPos, m_nSwapCardsWaitTimer))
					BroadcastPacket(&packet);
				m_status_endtimer = now() + m_nSwapCardsWaitTimer;
				return 0;
			}
			else if (m_i8SwapCardsPosType == enMJSwapCardsPosType_Default)
			{
				if (m_status_endtimer <= now())
				{
					CharPtr pChr = sCharMgr.load(m_vSeatPlayers[m_ui8BankerPos]->player._handle);
					PlayerChooseSwapCardsType(pChr, enMJSwapCardsPosType_Random, false);
				}
				return 0;
			}
			DealPlayerSwapCards();
			Wait(2000);
			return ChangeChannelState(en_MJChannelState_GiveCard);
		}

		if (m_status_endtimer <= now())
		{// 时间到
			// 没选牌的玩家，选默认的牌
			AutoChooseSwapCards();
		//	// 处理玩家换牌
		//	DealPlayerSwapCards();

		///*	if (m_nGameModeFlag & enPlayerMode_Que)
		//		return ChangeChannelState(en_MJChannelState_ChooseQue);
		//	else*/
		//		return ChangeChannelState(en_MJChannelState_GiveCard);
		}

		return 0;
	}


	// 定缺状态
	HSMState AIMaJiangChannelBaseInterface::battle_chooseque(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_ChooseQue);
			me->setChannelBattleChooseQue();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleChooseQueUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 定缺Init
	void AIMaJiangChannelBaseInterface::setChannelBattleChooseQue(void)
	{
		// 通知玩家定缺

		// WorldPacket packet;
		// if(sProtocolsMgr.CreateNoticeChooseQueColorPacket(&packet, m_nChooseQueWaitTimer))
			// BroadcastPacketCB(&packet);
		ChoosePlayerInitQueColor();
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJXuanQueNotifyPacket(&packet, pTp->ui8InitColor, m_nChooseQueWaitTimer ))
				SendProtocolToPlayer(&packet, i);
		}
		m_status_endtimer = now() + m_nChooseQueWaitTimer;
		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleChooseQue", "channel[%u] init choose que!", m_Unit->getHandle());
	}

	// 定缺Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleChooseQueUpdate(void)
	{
		
	WGS_MJCHANNEL_LOCK;
		
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return ChangeChannelState(m_next_run_status);
		bool bAll = true;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			
			
			if (pTp->ui8ChooseColor == 0)
			{
				bAll = false;
				// break;
			}
		}
		if (m_status_endtimer <= now() || bAll)
		{// 时间到，帮玩家选择定缺

			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if(pTp->ui8ChooseColor == 0)
					SystemAutoChooseQueColor(GetTablePlayerByPos(i));
			}

			// 发送玩家定缺消息
			SendAllPlayersQueInfo();
			return ChangeChannelState(en_MJChannelState_GiveCard);
		}

		return 0;
	}

	//-----------------------------------------------------------------------
	bool AIMaJiangChannelBaseInterface::PlayerChooseQue(CharPtr & pChr, const uint8 & que_color)
	{
		WGS_MJCHANNEL_LOCK
			if (!que_color || pChr.isNull())
				return false;

		if (m_run_status != en_MJChannelState_ChooseQue)
			return false;

		MJBaseTablePlayer * pTb = GetTablePlayer(pChr->getHandle());
		if (!pTb)
			return false;

		if (pTb->ui8ChooseColor )	//已经选择了缺了
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJPlayerXuanQueResultPacket(&packet, pTb->ui8ChooseColor, 0))
				sGLMgr.SendProtocolsToChr(pChr, &packet);
		}

		if (que_color > 3 || que_color < 1)
			return false;

		//设置缺的门
		pTb->ui8ChooseColor = que_color;

		

		 WorldPacket packet;
		 if(sProtocolsMgr.CreateMJPlayerXuanQueResultPacket(&packet, que_color,1))
			 sGLMgr.SendProtocolsToChr(pChr,&packet);

	

		Log.Notice("AIMaJiangChannelBaseInterface::PlayerChooseQue", "chn[%u] pos[%u] choose que[%u]", m_Unit->getHandle(), pTb->pos, que_color);
		return true;
	}

	//-----------------------------------------------------------------------
	void AIMaJiangChannelBaseInterface::SystemAutoChooseQueColor(MJBaseTablePlayer * tb)
	{
		if(tb->ui8ChooseColor == 0)
			tb->ui8ChooseColor = tb->ui8InitColor;
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJPlayerXuanQueResultPacket(&packet, tb->ui8ChooseColor, 1))
			SendProtocolToPlayer(&packet,tb->pos);
	}

	// 发送所有玩家定缺消息
	void AIMaJiangChannelBaseInterface::SendAllPlayersQueInfo()
	{
		WorldPacket packet;
		TablePlayerIter iter, ei = m_vSeatPlayers.end();
		std::vector<uint8>  temp;
		for (iter = m_vSeatPlayers.begin(); iter != ei; ++iter)
		{
			temp.push_back((*iter)->ui8ChooseColor);
		}
		if (sProtocolsMgr.CreateMJXuanQueListPacket(&packet, temp))
			BroadcastPacket(&packet);
	}

	void AIMaJiangChannelBaseInterface::SendProtocolToPlayer(WorldPacket * packet, MJBaseTablePlayer & tp)
	{
		SendProtocolToPlayer(packet, &tp);
	}

	//发送协议给玩家
	void AIMaJiangChannelBaseInterface::SendProtocolToPlayer(WorldPacket * packet, MJBaseTablePlayer * tp)
	{
		if (packet == NULL) return;
		if (tp == NULL)return;
		if (tp->player.isNull()) return;
		CharPtr pChr = sCharMgr.load(tp->player._handle);
		if (pChr.isNull())return;
		sGLMgr.SendProtocolsToChr(pChr, packet);
	}

	void AIMaJiangChannelBaseInterface::SendProtocolToPlayer(WorldPacket * packet, const uint8 & _pos)
	{
		SendProtocolToPlayer(packet, GetTablePlayerByPos(_pos));
	}

	//是否所有玩家都进行托管
	bool AIMaJiangChannelBaseInterface::IsAllPlayerTrusteeship()
	{
		bool result = true;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (m_ui8Trustee[i] == enPlayer_Normal || m_ui8Trustee[i] == enPlayer_AutoHuPai)
			{
				result = false;
				break;
			}
		}
		return result;
	}

	//是否所有可操作玩家都操作了
	bool AIMaJiangChannelBaseInterface::IsAllPlayerOperatorInOperatorState()
	{
		bool result = true;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (m_bResponse[i] == false && m_ui8UserAction[i] != WIK_NULL)
			{
				result = false;
				break;
			}
		}
		return result;
	}

	//移除手牌
	bool AIMaJiangChannelBaseInterface::RemoveCard(const uint8 & ui8TargetPos, std::vector<uint8> vecRemoveCards)
	{
		String temp = "";
		for (uint8 i = 0; i < vecRemoveCards.size(); i++)
		{
			temp += StringConverter::toString(vecRemoveCards[i]) + ",";
		}
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::RemoveCard", "user:%d removeCard:%s", ui8TargetPos, temp.c_str());
		m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8TargetPos], vecRemoveCards);
		return true;
	}

	//等待  
	void AIMaJiangChannelBaseInterface::Wait(const uint32 & _ms)
	{//慎用
		uint32 _time = now() + _ms;
		while (now() < _time);
	}

	//选择玩家默认缺花色
	void AIMaJiangChannelBaseInterface::ChoosePlayerInitQueColor()
	{
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			uint8* ui8CardIndex = new uint8[m_ui8MaxHandCount];
			uint8 ui8CardCount = 0;
			ZeroMemory(ui8CardIndex, sizeof(ui8CardIndex));
			for (uint8 k = 0; k < MAX_INDEX; k++)
			{
				for (uint8 t = 0; t < m_ui8UserCardIndex[i][k]; t++)
				{
					ui8CardIndex[ui8CardCount++] = m_GameLogic->SwitchToCardData(k);
				}
			}
			std::vector<CardInfo> temp;
			m_GameLogic->GetCardInfoList(ui8CardIndex, ui8CardCount, temp);
			sort(temp.begin(), temp.end());
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
			{
				
				pTp->ui8InitColor = temp[0].color;

				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr->isNPC())
				{
					
					pTp->ui8ChooseColor = pTp->ui8InitColor;
				}
			}
			if (ui8CardIndex)
			{
				delete[] ui8CardIndex;
			}
			ui8CardIndex = NULL;
		}
	}

	//扣除对局费
	void AIMaJiangChannelBaseInterface::DealDuiJuFei()
	{
		CenterBattle cb;
		sCenterBattleMgr.GetCenterBattle(m_btLog.cb_id, &cb);
		int nDuiJuFei = m_nBasePoint * m_GameLogic->GetDuiJuFei();
		if (nDuiJuFei == 0) return;
		stIncomeInfo stInfo;
		stInfo.game_id = m_btLog.game_id;
		stInfo.channel_id = m_Unit->getHandle();
		stInfo.town_id = m_Unit->getUInt32Field("town_id");
		stInfo.cb_id = m_btLog.cb_id;
		stInfo.join_code = m_Unit->getStringField("winner");
		stInfo.agent_id = m_btLog.agent_id;
		stInfo.loop_id = m_nLoopId;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
			{
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr.isNull() == NULL)
				{
					Log.Debug("AIMaJiangChannelBaseInterface::DealDuiJuFei", "Chr[%d] reduce:%d", pChr->getHandle(), nDuiJuFei);
					sGLMgr.reduceItemNum(pChr, ItemModel_Coins, nDuiJuFei);
					UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
					stIncomePlayerInfo temp;
					temp.model_id = ItemModel_Coins;
					temp.num = nDuiJuFei;
					if(pUser.isNull() == false)
						temp.pid = pUser->getUInt32Field("platform_id");
					stInfo.vPlayers.push_back(temp);
					WorldPacket packet;
					if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, pTp))
						BroadcastPacket(&packet);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_DuiJuCoins, cb.data1, en_UNT_Reduce, nDuiJuFei, m_btLog.cb_id, m_Unit->getHandle());

				}
			}
		}
		sGLMgr.AddPlayerIncomeInfoToUrl(stInfo);
	
	}

	//换牌
	void AIMaJiangChannelBaseInterface::SwapCards()
	{
		if (m_i8SwapCardsPosType == enMJSwapCardsPosType_Random)
		{
			m_i8SwapCardsPosType = RandomUInt(enMJSwapCardsPosType_D_U,enMJSwapCardsPosType_M);
			SwapCards();
			/*std::vector<uint8> vecSwapStatus(m_nMaxPlayerNum, 0);
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				uint8 ui8SwapPos = i;
				do
				{
					Log.Debug("IMaJiangChannelBaseInterface::SwapCards", "ui8SwapPos:%d i:%d  vecSwapStatus[ui8SwapPos]%d", ui8SwapPos,i, vecSwapStatus[ui8SwapPos]);
					ui8SwapPos = RandomUInt(m_nMaxPlayerNum - 1);
				} while (ui8SwapPos == i || vecSwapStatus[ui8SwapPos] == 1);
				MJBaseTablePlayer * pSwap = GetTablePlayerByPos(ui8SwapPos);
				vecSwapStatus[ui8SwapPos] = 1;
				pTp->vecSwapedCards = pSwap->vecSwapingCards;
				pTp->ui8SwapFrom = ui8SwapPos;
			}*/
		}
		else if (m_i8SwapCardsPosType == enMJSwapCardsPosType_M)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				uint8 ui8SwapPos = (i + 2 + m_nMaxPlayerNum) % m_nMaxPlayerNum;
				MJBaseTablePlayer * pSwap = GetTablePlayerByPos(ui8SwapPos);
				pTp->vecSwapedCards = pSwap->vecSwapingCards;
				pTp->ui8SwapFrom = ui8SwapPos;
			}
		}
		else if (m_i8SwapCardsPosType == enMJSwapCardsPosType_U_D)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				uint8 ui8SwapPos = (i FX -1 + m_nMaxPlayerNum) % m_nMaxPlayerNum;
				MJBaseTablePlayer * pSwap = GetTablePlayerByPos(ui8SwapPos);
				pTp->vecSwapedCards = pSwap->vecSwapingCards;
				pTp->ui8SwapFrom = ui8SwapPos;
			}
		}
		else if (m_i8SwapCardsPosType == enMJSwapCardsPosType_D_U)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				uint8 ui8SwapPos = (i FX 1 + m_nMaxPlayerNum) % m_nMaxPlayerNum;
				MJBaseTablePlayer * pSwap = GetTablePlayerByPos(ui8SwapPos);
				pTp->vecSwapedCards = pSwap->vecSwapingCards;
				pTp->ui8SwapFrom = ui8SwapPos;
			}
		}
	}

	//玩家选择换牌模式
	void AIMaJiangChannelBaseInterface::PlayerChooseSwapCardsType(CharPtr & pChr, const uint8 & ui8SwapPosType,bool bLock )
	{
		if (pChr.isNull())
			return ;
		if (bLock)
		{
			WGS_MJCHANNEL_LOCK;
			PlayerChooseSwapCardsType(pChr, ui8SwapPosType, false);
			return;
		}

		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());

		m_i8SwapCardsPosType = ui8SwapPosType;

		WorldPacket packet;
		if (sProtocolsMgr.CreateMJPlayerChooseSwapPosPacket(&packet, pTp->pos, m_i8SwapCardsPosType, 1))
			BroadcastPacket(&packet);

	}

	// 摸牌状态
	HSMState AIMaJiangChannelBaseInterface::battle_givecard(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_GiveCard);
			me->setChannelBattleGiveCard();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleGiveCardUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 摸牌Init
	void AIMaJiangChannelBaseInterface::setChannelBattleGiveCard(void)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleGiveCard", "channel[%u] !!!", m_Unit->getHandle());
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
		{
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleGiveCard", "m_next_run_status", m_next_run_status);
			return;

		}
		if (m_bVoting)
		{
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleGiveCard", "m_bVoting", m_bVoting);
			return;

		}
		// 摸牌
		if (m_ui8CurrentPos == INVALID_uint8)
		{
			Log.Error("AIMaJiangChannelBaseInterface::setChannelBattleGiveCard", "m_ui8CurrentPos:255 m_ui8ResumePos:%d", m_ui8ResumePos);
			m_ui8CurrentPos = m_ui8ResumePos;
		}
		setStatusEndTimer(m_GameLogic->GetChannelTime("AGiveHandCardTime"));
	}

	// 摸牌Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleGiveCardUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;

		if (m_bVoting)
			return ChangeChannelState(m_next_run_status);
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return ChangeChannelState(m_next_run_status);

		if (now() > getStatusEndTimer())
		{
			DispatchCardData(m_ui8CurrentPos);

			return ChangeChannelState(m_next_run_status); // 进入出牌状态
		}
		return 0;
	}

	// 出牌状态
	HSMState AIMaJiangChannelBaseInterface::battle_castcard(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_CastCard);
			me->setChannelBattleCastCard();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleCastCardUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 出牌Init
	void AIMaJiangChannelBaseInterface::setChannelBattleCastCard(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return;
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleCastCard", "channel[%u] m_ui8CurrentPos[%d] m_ui8Trustee[m_ui8CurrentPos]:%d ", m_Unit->getHandle(), m_ui8CurrentPos, m_ui8Trustee[m_ui8CurrentPos]);
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJCastCardNotify(&packet, m_ui8CurrentPos, m_nCastHandCardTime))
			BroadcastPacket(&packet);
		setStatusEndTimer(m_nCastHandCardTime);
	}

	// 出牌Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleCastCardUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return ChangeChannelState(m_next_run_status);

		if (m_bVoting)
			return ChangeChannelState(m_next_run_status);

		if (now() > getStatusEndTimer() || m_bAnyOperate || m_ui8Trustee[m_ui8CurrentPos] != enPlayer_Normal)
		{
			if (m_bOverTimeWait == false)
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleCastCard", "m_ui8Trustee[%d]：%d m_bAnyOperate:%d", m_ui8CurrentPos, m_ui8Trustee[m_ui8CurrentPos], m_bAnyOperate);

			if (m_ui8Trustee[m_ui8CurrentPos] != enPlayer_Normal && m_bAnyOperate == false)
			{//托管中
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(m_ui8CurrentPos);
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (m_bOverTimeWait == false || m_ui8Trustee[m_ui8CurrentPos] == enPlayer_AutoHuPai || pChr->isNPC())
				{

					Wait(500);
					AutoOperate(m_ui8CurrentPos);
				}
				else
				{
					m_bAnyOperate = false;
					return 0;
				}
			}
			else if (m_ui8Trustee[m_ui8CurrentPos] == enPlayer_Normal && m_bAnyOperate == false)
			{//未操作
				if (m_bOverTimeWait == false)
				{
					m_ui8Trustee[m_ui8CurrentPos] = enPlayer_Trusteeship;
					SendPlayerStatus(m_ui8CurrentPos, enPlayer_Trusteeship);
					Wait(500);
					AutoOperate(m_ui8CurrentPos);
				}
				else
					return 0;
			}
			m_bAnyOperate = false;
			return ChangeChannelState(m_next_run_status);
		}
		return 0;
	}

	// 操作牌状态
	HSMState AIMaJiangChannelBaseInterface::battle_operatorcard(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_OperatorCard);
			me->setChannelBattleOperatorCard();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleOperatorCardUpdate)
			return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 操作牌Init
	void AIMaJiangChannelBaseInterface::setChannelBattleOperatorCard(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return;
		if (m_bVoting)
			return;
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleOperatorCard", "channel[%u] !!!", m_Unit->getHandle());


		uint32 temp = m_nOperatorCardTime;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (m_bBaoJiao[i] == true && m_ui8Trustee[i] == enPlayer_AutoHuPai && (m_ui8UserAction[i] & WIK_GANG) == WIK_GANG && (m_ui8UserAction[i] & WIK_CHI_HU) != WIK_CHI_HU)
			{
				m_nOperatorCardTime = 10000;
				break;
			}
		}
		//发送操作通知
		SendOperateNotify();

		bool bCast = false;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (m_ui8UserAction[i])
			{
				bCast = true;
				break;
			}
		}
		if (bCast == false)
		{
			m_bAnyOperate = true;
			m_next_run_status = en_MJChannelState_CastCard;
			return;
		}

		setStatusEndTimer(m_nOperatorCardTime);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
			{
				if (m_ui8Trustee[i] != enPlayer_Normal && m_ui8UserAction[i] != WIK_NULL)
				{
					if (m_bBaoJiao[i] == true && m_ui8Trustee[i] == enPlayer_AutoHuPai && (m_ui8UserAction[i] & WIK_GANG) == WIK_GANG && (m_ui8UserAction[i] & WIK_CHI_HU) != WIK_CHI_HU)
					{

					}
					else if (m_ui8Trustee[i] == enPlayer_AutoHuPai && (m_ui8UserAction[i] & WIK_GANG) == WIK_GANG && (m_ui8UserAction[i] & WIK_CHI_HU) != WIK_CHI_HU)
					{

					}
					else
					{
						m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::setChannelBattleOperatorCard", "channel[%u] i[%d] pTp[%d] m_ui8Trustee[i]:%d", m_Unit->getHandle(),i,pTp->pos, m_ui8Trustee[i]);

						AutoOperate(pTp->pos);
					}
				}
			}
		}
		m_nOperatorCardTime = temp;


	
	
	}

	// 操作牌Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleOperatorCardUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return ChangeChannelState(m_next_run_status);
		if (m_bVoting)
			return ChangeChannelState(m_next_run_status);
		//玩家全部托管
		if (IsAllPlayerTrusteeship())
		{
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::IsAllPlayerTrusteeship", "channel[%u] !!!", m_Unit->getHandle());
			if (m_next_run_status == en_MJChannelState_GiveCard &&  m_ui8CurrentPos == INVALID_uint8)
			{
				m_ui8CurrentPos = m_ui8ResumePos;
			}
			return ChangeChannelState(m_next_run_status);
		}
		bool bAllPlayerOperator = IsAllPlayerOperatorInOperatorState();



		if (now() > getStatusEndTimer() || m_ui8AllPlayerOperatorStatus == enAllPlayerOperatorStatus_AllPlayerOperator || bAllPlayerOperator || m_bAnyOperate)
		{
			if (m_ui8AllPlayerOperatorStatus == enAllPlayerOperatorStatus_AllPlayerOperator)
				return ChangeChannelState(m_next_run_status);
			if (m_bAnyOperate)
			{
				m_bAnyOperate = false;
				return ChangeChannelState(m_next_run_status);
			}
			if (m_bOverTimeWait == false)
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::ChannelBattleOperatorCardUpdate", "bAllPlayerOperator :%d !!!", bAllPlayerOperator);
			if (bAllPlayerOperator == false)
			{//有玩家未操作
				for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
				{
					MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
					if (pTp)
					{
						CharPtr pChr = sCharMgr.load(pTp->player._handle);
						if (m_bOverTimeWait == false)
							m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::ChannelBattleOperatorCardUpdate", "i:%d  m_bResponse[%d]:%d!!m_ui8UserAction[i]:%d", i, i, m_bResponse[i], m_ui8UserAction[i]);
						if (m_bResponse[i] == false && m_ui8UserAction[i] != WIK_NULL)
						{
							if (m_bOverTimeWait == false)
							{//操作超时是否进入托管
								/*if (m_ui8Trustee[i] != enPlayer_Normal)
								{
									m_ui8Trustee[i] = enPlayer_Trusteeship;
									SendPlayerStatus(i, enPlayer_Trusteeship);
								}*/
								AutoOperate(pTp->pos);
							}
							else if (pChr->isNPC())
							{
								AutoOperate(pTp->pos);
							}
							else
							{

								return 0;
							}
						}
					}
				}
			}

			if (m_next_run_status == en_MJChannelState_GiveCard &&  m_ui8CurrentPos == INVALID_uint8)
			{
				m_ui8CurrentPos = m_ui8ResumePos;
			}
			if (m_next_run_status == en_MJChannelState_CastCard && m_ui8CurrentPos != m_ui8ProvidePos)
			{
				//听牌
				if (m_GameLogic->AllowedTing())
				{
					if (IsEstimateTing(m_ui8CurrentPos, m_uint8SendCardData))
					{
						if (m_bBaoJiao[m_ui8CurrentPos] != true)
						{
							if (WIK_LISTEN == AnalyseTingCard(m_ui8CurrentPos))
							{
								//	if(m_bOutCardTingList == false)
								m_ui8UserAction[m_ui8CurrentPos] |= WIK_LISTEN;
							}
						}
					}
				}

				if (m_ui8UserAction[m_ui8CurrentPos] != 0)
					m_next_run_status = en_MJChannelState_OperatorCard;
			}
			m_bAnyOperate = false;
			return ChangeChannelState(m_next_run_status);
		}
		return 0;
	}

	// 结算状态
	HSMState AIMaJiangChannelBaseInterface::battle_calc(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_GameOverCalc);
			me->setChannelBattleCalc();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleCalcUpdate)
				return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 结算Init
	void AIMaJiangChannelBaseInterface::setChannelBattleCalc(void)
	{
		if (m_nCB_id == 0)
		{
			settleAccounts();
			m_next_run_status = en_MJChannelState_Prep;
		}
		else
		{
			CenterBattleDeal();
		}
	}

	// 结算Update
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChannelBattleCalcUpdate(void)
	{
		if (m_next_run_status == en_MJChannelState_Close)
		{
			if (now() < getStatusEndTimer())
				return 0;
		}
		return ChangeChannelState(m_next_run_status);
	}

	// 起手补牌Update
	HSMStateHandler AIMaJiangChannelBaseInterface::ChannelBattleSendCardsBuPaiUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;

		if (m_next_run_status == en_MJChannelState_GameOverCalc || m_run_status == en_MJChannelState_GameOverCalc)
		{
			return ChangeChannelState(m_next_run_status);
		}

		GameStartBuHua();

		return ChangeChannelState(m_next_run_status);
	}

	HSMStateHandler AIMaJiangChannelBaseInterface::ChannelBattleGiveCardsBuPaiUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc || m_run_status == en_MJChannelState_GameOverCalc)
		{
			return ChangeChannelState(m_next_run_status);
		}

		if (now() > getStatusEndTimer())
		{

		}
		return 0;
	}

	HSMStateHandler AIMaJiangChannelBaseInterface::ChannelBattleSameIPCheckUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;
		if (m_next_run_status == en_MJChannelState_GameOverCalc || m_run_status == en_MJChannelState_GameOverCalc)
		{
			return ChangeChannelState(m_next_run_status);
		}

		if (now() > getStatusEndTimer() || m_bThinkSameIP == false)
		{
			bool _ok = true;
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer  * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL)
					continue;
				if (pTp->m_ui8SameIPStatus == enSameIPStatus_Refuse || pTp->m_ui8SameIPStatus == enSameIPStatus_Think)
				{
					pTp->nAgreePlayerGame = enAgreeOrRefuse_None;
					pTp->playerJoinState = MJ_PlayerReadyStatus_Join;
					_ok = false;
				}
			}
			m_bThinkSameIP = true;
			if (_ok)
			{
				m_bHaveSameIP = false;
			}
			else
			{
				for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
				{
					MJBaseTablePlayer  * pTp = GetTablePlayerByPos(i);
					if (pTp == NULL)
						continue;
					pTp->nAgreePlayerGame = enAgreeOrRefuse_None;
					pTp->playerJoinState = MJ_PlayerReadyStatus_Join;
					pTp->m_ui8SameIPStatus = enSameIPStatus_Think;
					_ok = false;
					WorldPacket packet;
					if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, pTp))
						BroadcastPacket(&packet);

				}
			}

			return ChangeChannelState(en_MJChannelState_Prep);

		}

		return 0;
	}



	// 牌桌结束状态
	HSMState AIMaJiangChannelBaseInterface::battle_close(AIMaJiangChannelBaseInterface *me, HSMEvent const *e)
	{
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_Close);
			me->setChannelBattleClose();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 牌桌自定义状态
	HSMState AIMaJiangChannelBaseInterface::battle_custom(AIMaJiangChannelBaseInterface * me, HSMEvent const * e)
	{
		using namespace AIScript;
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_Custom);
			me->ChangeChannelPublicFun();
			me->RunPublicBattelStateInit();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(RunPublicBattelUpdate);
			return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 起手补牌状态状态
	HSMState AIMaJiangChannelBaseInterface::battle_sendcardsbupai(AIMaJiangChannelBaseInterface * me, HSMEvent const * e)
	{
		using namespace AIScript;
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_SendCardsBuPai);
			me->setChannelBattleSendCardsBuPai();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleSendCardsBuPaiUpdate);
			return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	HSMState AIMaJiangChannelBaseInterface::battle_gviecardsbupai(AIMaJiangChannelBaseInterface * me, HSMEvent const * e)
	{
		using namespace AIScript;
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_GiveCardsBuPai);
			me->setChannelBattleGiveCardBuPai();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleGiveCardsBuPaiUpdate);
			return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}

	// 牌桌同ip检测
	HSMState AIMaJiangChannelBaseInterface::battle_sameipcheck(AIMaJiangChannelBaseInterface * me, HSMEvent const * e)
	{
		using namespace AIScript;
		switch (e->sig)
		{
		case HSM_INIT_SIG:
			me->setRunStatus(en_MJChannelState_SameIP);
			me->setChannelBattleSameIPCheck();
			return HSM_HANDLED();
		case HSM_UPDATE_SIG:
			VCALL(ChannelBattleSameIPCheckUpdate);
			return HSM_HANDLED();
		}

		return HSM_SUPER(&Hsm::hsm_top);
	}



	//================================定庄相关函数

	//随机产生庄家
	void AIMaJiangChannelBaseInterface::MakeRandBanker()
	{
		// 随机庄家
		do
		{

		
			uint32 point = m_dice[0] + m_dice[1];
			switch (point)
			{
			case 5:
			case 9:
				m_ui8BankerPos = 0;
				break;
			case 2:
			case 6:
			case 10:
				m_ui8BankerPos = 1;
				break;
			case 3:
			case 7:
			case 11:
				m_ui8BankerPos = 2;
				break;
			case 4:
			case 8:
			case 12:
				m_ui8BankerPos = 3;
				break;
			}
		} while (m_ui8BankerPos > m_nMaxPlayerNum - 1);
	}

	//================================发牌相关函数

	//游戏每局开始时发初始手牌
	void AIMaJiangChannelBaseInterface::DistributeInitalHandCards(const uint8 & ui8CardNum)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DistributeInitalHandCards", "m_uint8LeftCardCount:%d", m_uint8LeftCardCount);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			m_bPlayStatus[i] = true;
			m_bHasHuPai[i] = false;
			m_uint8LeftCardCount -= (ui8CardNum);
			m_GameLogic->Licensing(m_uint8RepertoryCard, m_uint8LeftCardCount, ui8CardNum, m_ui8UserCardIndex[i], pTp->m_vecHandCardsList);
		}
		//	SendTableStatus(0);
	}

	void AIMaJiangChannelBaseInterface::TestHandCards()
	{
		if (m_GameLogic->IsUsePeiPai())
		{
			if (m_GameLogic->GetTestCardsMode() == enTestCardsMode_Code)
			{
				uint8 byte[] = {

					41,41,41,41,									//东风
					42,42,42,42,									//南风
					43,43,43,43,									//西风
					44,44,44,44,									//北风
					51,51,51,51,									//中
					52,52,52,52,									//发
					53,53,53,53,									//白
					11,12,13,14,15,16,17,
					11,12,13,14,15,16,17,
					11,12,13,14,15,16,17,

					26,27,28,24,25,26,27,
					23,22,28,24,25,26,27,
					33,22,23,25,25,26,27,

					31,32,33,34,35,21,21,
					21,14,13,13,13,11,14,

					18,41,42,42,44,44,11,11,11,51,52,53,16,

					18,18,44,44,43,43,42,42,52,52,22,25,27,

					29,29,29,29,28,28,28,28,18,18,18,18,25,

					41,42,44,51,15,15,15,15,21,21,21,21,26,


				};
				std::vector<uint8> temp(byte, byte + MAX_REPERTORY_FENGZIPAI);
				m_uint8RepertoryCard = temp;
				m_ui8BankerPos = 0;
			}
			else if (m_GameLogic->GetTestCardsMode() == enTestCardsMode_Json)
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::TestHandCards", "m_ui8StartTestCardsIndex[%d]", m_ui8StartTestCardsIndex);
				if (m_ui8StartTestCardsIndex >= m_GameLogic->GetTestCardsMaxIndex())
				{
					if (m_GameLogic->IsTestCardsRepeat())
					{
						m_ui8StartTestCardsIndex = 0;
					}
					else
						return;
				}
				m_GameLogic->TestShuffleCards(m_uint8RepertoryCard, m_ui8StartTestCardsIndex, m_ui8BankerPos);
				m_ui8StartTestCardsIndex++;
			}
		}
	}

	//发送手牌列表
	void AIMaJiangChannelBaseInterface::SendHandCards(const uint8 & ui8PlayerPosID, const uint8 & type, bool bReconnection)
	{
		std::vector<uint8>  vecCards;
		m_GameLogic->SwitchToCardData(m_ui8UserCardIndex[ui8PlayerPosID], vecCards);
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::SendHandCards", "vecCards:%d", vecCards.size());
		WorldPacket packet;
		if (bReconnection)
		{
			std::vector<uint8 >  vecCardCount;
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				vecCardCount.push_back(m_GameLogic->GetCardCount(m_ui8UserCardIndex[i]));
			}
			uint8 ui8lastCard = m_uint8SendCardData;
			//if(m_run_status == en_MJChannelState_CastCard)
			if (m_ui8CurrentPos != ui8PlayerPosID) ui8lastCard = 0;
			if(ui8lastCard != 0)
			if (m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(ui8lastCard)] == 0)ui8lastCard = 0;
			if (sProtocolsMgr.CreateMJReconnectionPacket(&packet, vecCards, vecCardCount, m_WeaveItemArray, m_ui8DiscardCard, ui8lastCard))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
		}
		else
		{
			if (sProtocolsMgr.CreateMJHandCardPacket(&packet, vecCards, type))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
		}

	}

	//发牌
	bool AIMaJiangChannelBaseInterface::DispatchCardData(const uint8 & ui8PlayerPosID, bool isTail)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "m_uint8LeftCardCount:%d", m_uint8LeftCardCount);
		if (ui8PlayerPosID == INVALID_uint8)
			return false;

		//丢牌
		if ((m_ui8OutCardPos != INVALID_uint8) && (m_ui8OutCardData != 0))
		{
			//	m_ui8DiscardCount[m_ui8OutCardPos]++;
			m_ui8DiscardCard[m_ui8OutCardPos].push_back(m_ui8OutCardData);
		}

		//荒庄
		if (GameLoopOver())
		{
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "GameLoopOver");
			m_ui8ChiHuCard = 0;
			m_ui8ProvidePos = INVALID_uint8;
			BeforeGameOverCalc();
			//m_next_run_status = en_MJChannelState_GameOverCalc;
			return true;
		}
		m_bAnyOperate = false;
		m_ui8OutCardData = 0;
		m_ui8CurrentPos = ui8PlayerPosID;
		m_ui8OutCardPos = INVALID_uint8;
		m_bEnjoinChiHu[ui8PlayerPosID] = false;
		m_vecLouHuCards[ui8PlayerPosID].clear();
		m_ui8AllPlayerOperatorStatus = enAllPlayerOperatorStatus_Close;
		m_ui8UserAction[ui8PlayerPosID] = 0;
		m_bGangOutStatus = false;
		m_bGangStatus = false;
		bool bBuPai = false;

		//发牌
		if (m_bSendStatus)
		{
			//发牌数据更新
			m_uint8SendCardCount++;
			m_uint8SendCardData = m_uint8RepertoryCard[--m_uint8LeftCardCount];
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "ui8PlayerPosID:%d m_uint8SendCardData:%d", ui8PlayerPosID, m_uint8SendCardData);

			if (IsHuaPai(m_uint8SendCardData))
			{
				bBuPai = true;
		/*	//	m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(m_uint8SendCardData)]++;
				uint8 ui8CardTemp = DealHuaPai(ui8PlayerPosID, m_uint8SendCardData);
				if (m_GameLogic->IsValidCard(ui8CardTemp))
				{
					bBuPai = true;
					m_uint8SendCardData = ui8CardTemp;
				}
				else
				{
					if(m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(m_uint8SendCardData)])
						m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(m_uint8SendCardData)]--;
				}*/
			}
			if (bBuPai == false)
			{
				m_ui8ProvideCard = m_uint8SendCardData;
				m_ui8ProvidePos = ui8PlayerPosID;
				m_ui8SendCardPos = m_ui8ProvidePos;
				if (m_bBuPai)
					m_ui8BuCard = m_uint8SendCardData;
				else
					m_ui8BuCard = 0;
				m_bBuPai = false;
			}
			else
			{
				m_ui8BuCard = 0;
			}
			//胡牌判断
			if (m_GameLogic->AllowedZiMoHu())
			{
				CChiHuRight ChiHuRight;
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "AnalyseHuCard");
				if (IsEstimateHu(ui8PlayerPosID, ui8PlayerPosID, m_uint8SendCardData))
				{
					uint8 isHu = AnalyseHuCard(ui8PlayerPosID, m_ui8UserCardIndex[ui8PlayerPosID], m_WeaveItemArray[ui8PlayerPosID], m_uint8SendCardData, ChiHuRight);
					if (isHu != WIK_NULL && isHu != WIK_CHI_HU)
					{
						Log.Error("AIMaJiangChannelBaseInterface::DispatchCardData", "AnalyseHuCard return:%d", isHu);
						ASSERT(0);
					}
					m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "isHu:%d", isHu);
					m_ui8UserAction[ui8PlayerPosID] |= isHu;
				}
			}


			//加牌
			m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(m_uint8SendCardData)]++;

			if (bBuPai == false)
			{
				//听牌
				if (m_GameLogic->AllowedTing())
				{
					if (IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData))
					{
						if (m_bBaoJiao[ui8PlayerPosID] != true)
						{
							if (WIK_LISTEN == AnalyseTingCard(ui8PlayerPosID))
							{
								m_ui8UserAction[ui8PlayerPosID] |= WIK_LISTEN;
							}
						}
					}
				}
				//			Log.Error("AIMaJiangChannelBaseInterface::DispatchCardData", "////////////////////////");


				//杠牌判断
				if (m_bEnjoinChiPeng[ui8PlayerPosID] == false && m_uint8LeftCardCount > 0)
				{
					if (IsEstimateGang(ui8PlayerPosID, ui8PlayerPosID, m_uint8SendCardData))
					{
						m_VPlayerGangCardList[ui8PlayerPosID].clear();
						m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "AnalyseGangCard");
						uint8 result = m_GameLogic->AnalyseGangCard(m_ui8UserCardIndex[ui8PlayerPosID],
							m_WeaveItemArray[ui8PlayerPosID], m_uint8SendCardData,
							m_VPlayerGangCardList[ui8PlayerPosID]);
						if (result == WIK_GANG)
						{
							if (m_bBaoJiao[ui8PlayerPosID] == true || m_ui8Trustee[ui8PlayerPosID] == enPlayer_AutoHuPai)
							{
								if (TingEstimateGang(ui8PlayerPosID, m_uint8SendCardData))
									m_ui8UserAction[ui8PlayerPosID] |= result;
								else
								{
									m_VPlayerGangCardList[ui8PlayerPosID].clear();
								}
							}
							else
								m_ui8UserAction[ui8PlayerPosID] |= result;

						}
						m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DispatchCardData", "AnalyseGangCard end");
					}
				}
			}
		}
		////牌墙信息
		/*if (m_ui8HeapHand == INVALID_uint8 || m_ui8HeapTail == INVALID_uint8)
		{
			Log.Error("AIMaJiangChannelBaseInterface::DispatchCardData", "m_ui8HeapHand %d or m_ui8HeapTail %d error", m_ui8HeapHand, m_ui8HeapTail);
			ASSERT(0);
		}*/
		////不是摸领上牌
		//if (!isTail)
		//{
		//	uint8 ui8HeapCount = m_ui8HeapCardInfo[m_ui8HeapHand][0] + m_ui8HeapCardInfo[m_ui8HeapHand][1];
		//	if (ui8HeapCount == HEAP_FULL_COUNT)
		//		m_ui8HeapHand = (m_ui8HeapHand + 1) % CountArray(m_ui8HeapCardInfo);
		//	m_ui8HeapCardInfo[m_ui8HeapHand][0]++;
		//}
		//else
		//{
		//	uint8 ui8HeapCount = m_ui8HeapCardInfo[m_ui8HeapHand][0] + m_ui8HeapCardInfo[m_ui8HeapHand][1];
		//	if (ui8HeapCount == HEAP_FULL_COUNT)
		//		m_ui8HeapTail = (m_ui8HeapTail + 3) % CountArray(m_ui8HeapCardInfo);
		//	m_ui8HeapCardInfo[m_ui8HeapTail][1]++;
		//}

		CMD_SendCard SendCard;
		SendCard.ui8CardData = m_uint8SendCardData;
		SendCard.ui8CurrentPos = ui8PlayerPosID;
		SendCard.ui32LeftTime = m_nCastHandCardTime;
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJSendCardPacket(&packet, SendCard))
			SendProtocolToPlayer(&packet, SendCard.ui8CurrentPos);
		PlayBack(&packet);

		SendCard.ui8CardData = 0;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (i == ui8PlayerPosID) continue;
			if (sProtocolsMgr.CreateMJSendCardPacket(&packet, SendCard))
				SendProtocolToPlayer(&packet, i);

		}

		setStatusEndTimer(m_nAGiveHandCardTime);

		if (m_ui8UserAction[ui8PlayerPosID] != WIK_NULL && bBuPai == false)
		{
			m_next_run_status = en_MJChannelState_OperatorCard;
		}
		else if (bBuPai == true)
		{
			Wait(1000);
			DealHuaPai(ui8PlayerPosID, m_uint8SendCardData);
			m_bBuPai = true;
			m_next_run_status = en_MJChannelState_GiveCard;
		}
		else
		{
			m_next_run_status = en_MJChannelState_CastCard;
		}
		OperateDispatchCardData(ui8PlayerPosID, m_uint8SendCardData);
		return true;
	}

	//补牌		
	uint8 AIMaJiangChannelBaseInterface::CompensateCard(const uint8 & ui8PlayerPosID, std::vector<uint8> vecCardList)
	{
		uint8 ui8CardCount = vecCardList.size();
		uint8 ui8GetCard = 0;
		
		if (m_uint8LeftCardCount < ui8CardCount)
			ui8CardCount = m_uint8LeftCardCount;
		else if (m_uint8LeftCardCount - ui8CardCount < m_ui8LiuJuCardNum)
		{
			Log.Success("AIMaJiangChannelBaseInterface::CompensateCard", "m_ui8LiuJuCardNum[%d] m_uint8LeftCardCount[%d]", m_ui8LiuJuCardNum, m_uint8LeftCardCount);
			if (m_ui8LiuJuCardNum <= m_uint8LeftCardCount)
				ui8CardCount = m_uint8LeftCardCount - m_ui8LiuJuCardNum;
			else
			{
				Log.Error("AIMaJiangChannelBaseInterface::CompensateCard", "m_ui8LiuJuCardNum[%d] m_uint8LeftCardCount[%d]", m_ui8LiuJuCardNum, m_uint8LeftCardCount);
				Log.Error("AIMaJiangChannelBaseInterface::CompensateCard", "m_ui8LiuJuCardNum[%d] m_uint8LeftCardCount[%d]", m_ui8LiuJuCardNum, m_uint8LeftCardCount);
				Log.Error("AIMaJiangChannelBaseInterface::CompensateCard", "m_ui8LiuJuCardNum[%d] m_uint8LeftCardCount[%d]", m_ui8LiuJuCardNum, m_uint8LeftCardCount);
				ASSERT(0);
			}
		}

		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::CompensateCard", "ui8CardCount:%d m_uint8LeftCardCount:%d m_ui8LiuJuCardNum:%d vecCardList.size:%d", ui8CardCount, m_uint8LeftCardCount, m_ui8LiuJuCardNum, vecCardList.size());
		if (ui8CardCount == 0)
		{
			return ui8GetCard;
		}

		std::vector<uint8 > vecSwapList(vecCardList.begin(), vecCardList.begin() + ui8CardCount);

		std::vector<uint8> newCardList,SendCardList;
		for (uint8 i = 0; i < vecSwapList.size(); i++)
		{
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::CompensateCard", "CompensateCard pos[%d] card[%d]", ui8PlayerPosID, vecSwapList[i]);
			uint8 huaPai = vecSwapList[i];
		//	uint8 ui8CardData = m_uint8RepertoryCard[--m_uint8LeftCardCount];
		//	m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(ui8CardData)]++;
			m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(huaPai)]--;
			m_ui8HuaPaiList[ui8PlayerPosID].push_back(huaPai);
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::CompensateCard", "CompensateCard pos[%d] m_ui8HuaPaiList[%d] vecSwapList[i][%d] huaPai[%d]", ui8PlayerPosID, m_ui8HuaPaiList[ui8PlayerPosID].back(), vecSwapList[i], huaPai);
		//	newCardList.push_back(ui8CardData);
			SendCardList.push_back(0);
		//	ui8GetCard = ui8CardData;
		}
		WorldPacket packet;
	/*	if (sProtocolsMgr.CreateMJBuHuaListPacket(&packet, ui8PlayerPosID, m_ui8HuaPaiList[ui8PlayerPosID].back()))
			SendProtocolToPlayer(&packet, ui8PlayerPosID);*/
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
		//	if (i != ui8PlayerPosID)
			{
				if (sProtocolsMgr.CreateMJBuHuaListPacket(&packet, ui8PlayerPosID, m_ui8HuaPaiList[ui8PlayerPosID].back()))
					SendProtocolToPlayer(&packet, i);
			}
		}

		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::CompensateCard", "CompensateCard pos[%d] card[%d]", ui8PlayerPosID, m_ui8HuaPaiList[ui8PlayerPosID].back());
		/*if (sProtocolsMgr.CreateMJPlayerHuaPaiListPacket(&packet, ui8PlayerPosID, m_ui8HuaPaiList[ui8PlayerPosID]))
			BroadcastPacket(&packet);*/

		//std::vector<uint8> newNewCardList;
		//for (uint8 i = 0; i < newCardList.size(); i++)
		//{
		//	if (IsHuaPai(newCardList[i]))
		//	{
		//		newNewCardList.push_back(newCardList[i]);

		//	}
		//}
		//if (newNewCardList.size())
		//{
		////	Wait(1000);
		////	ui8GetCard = CompensateCard(ui8PlayerPosID, newNewCardList);
		//}
		Wait(m_GameLogic->GetChannelTime("ABuHuaTime"));
		return ui8GetCard;
	}

	//是否是花牌
	bool AIMaJiangChannelBaseInterface::IsHuaPai(const uint8 & ui8CardData)
	{
		if(m_GameLogic->GetCardColor(ui8CardData) == CARD_COLOR_Flower)
			return true;
		return false;
	}

	//处理花牌
	uint8 AIMaJiangChannelBaseInterface::DealHuaPai(const uint8 ui8PlayerPosID,const uint8 & ui8CardData)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DealHuaPai", "DealHuaPai pos[%d] card[%d]", ui8PlayerPosID, ui8CardData);
		if (IsHuaPai(ui8CardData))
		{
			return CompensateCard(ui8PlayerPosID, std::vector<uint8>(1,ui8CardData));
		}
		return 0;
	}

	//起手补花
	void AIMaJiangChannelBaseInterface::GameStartBuHua()
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::GameStartBuHua", "channel[%u] cb_id[%u] !", m_Unit->getHandle(), m_btLog.cb_id);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			uint8 ui8Pos = (m_ui8BankerPos + i + m_nMaxPlayerNum) % m_nMaxPlayerNum ;
			if (m_vecStartBuPaiStatus[ui8Pos] == enStartBuPai_Init)
			{
				std::vector<uint8> vecHuaPaiCard;
				do
				{
					vecHuaPaiCard.clear();
					for (uint8 t = 0; t < MAX_INDEX; t++)
					{
						if (m_ui8UserCardIndex[ui8Pos][t] == 0) continue;
						uint8 ui8CardData = m_GameLogic->SwitchToCardData(t);

						if (IsHuaPai(ui8CardData))
						{
							vecHuaPaiCard.push_back(ui8CardData);
							break;	
						}
					}
					if (vecHuaPaiCard.size())
					{
					
						CompensateCard(ui8Pos, vecHuaPaiCard);
						uint8 ui8CardData = m_uint8RepertoryCard[--m_uint8LeftCardCount];
						m_ui8UserCardIndex[ui8Pos][m_GameLogic->SwitchToCardIndex(ui8CardData)]++;
						CMD_SendCard SendCard;
						SendCard.ui8CardData = ui8CardData;
						SendCard.ui8CurrentPos = ui8Pos;
						SendCard.ui32LeftTime = 0;
						WorldPacket packet;
						if (sProtocolsMgr.CreateMJSendCardPacket(&packet, SendCard))
							SendProtocolToPlayer(&packet, SendCard.ui8CurrentPos);
						SendCard.ui8CardData = 0;
						for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
						{
							if (i == ui8Pos) continue;
							if (sProtocolsMgr.CreateMJSendCardPacket(&packet, SendCard))
								SendProtocolToPlayer(&packet, i);
						}
						Wait(m_GameLogic->GetChannelTime("ABuHuaTime"));
					}
				} while (vecHuaPaiCard.size());
			}
			m_vecStartBuPaiStatus[ui8Pos] = enStartBuPai_End;
		}
		m_next_run_status = en_MJChannelState_GiveCard;
	}

	//听牌
	uint8 AIMaJiangChannelBaseInterface::AnalyseTingCard(std::vector<uint8> vecCardIndex, std::vector<tagWeaveItem>& vecWeave, std::map<uint8, std::vector<uint8> > & mapTingPaiList)
	{
		std::vector<uint8 > vecCardIndexTemp = vecCardIndex;

		mapTingPaiList.clear();

		uint8  ui8CardNumCount = m_GameLogic->GetCardCount(vecCardIndexTemp);

		uint8  ui8MgicCardNum = m_GameLogic->GetMagicCardNum(vecCardIndex);
		if (ui8MgicCardNum > 1) return WIK_NULL;
		if ((ui8CardNumCount - 2) % 3 == 0)
		{//摸牌后出牌是否能听牌
			for (uint8 i = 0; i < MAX_INDEX; i++)
			{
				if (vecCardIndexTemp[i] == 0) continue;

				vecCardIndexTemp[i]--;
				std::vector<uint8 > resultTemp;
				for (uint8 t = 0; t < MAX_INDEX; t++)
				{
					if (m_GameLogic->IsMagicCard(t)) continue;
					CChiHuRight chr;
					uint8 ui8CardData = m_GameLogic->SwitchToCardData(t);
					uint32 __time = now();
					if (WIK_CHI_HU == AnalyseHuCard(vecCardIndexTemp, vecWeave, ui8CardData, chr))
					{
						resultTemp.push_back(m_GameLogic->SwitchToCardData(t));
						if (ui8MgicCardNum > 1) return WIK_LISTEN;
					}
					if (now() - __time > 1000)
					{
						String str = "";
						for (uint8 y = 0; y < MAX_INDEX; y++)
						{
							if (vecCardIndexTemp[y])
							{
								for (uint8 k = 0; k < vecCardIndexTemp[y]; k++)
								{
									str += StringConverter::toString(y) + ",";
								}
							}
						}
						Log.Success("AIMaJiangChannelBaseInterface::AnalyseTingCard", "str:%s ui8CardData:%d", str.c_str(), ui8CardData);
					}
				}
				if (resultTemp.size())
					mapTingPaiList.insert(std::make_pair(m_GameLogic->SwitchToCardData(i), resultTemp));
				vecCardIndexTemp[i]++;
			}
		}
		else
		{//查叫是否听牌
			for (uint8 t = 0; t < MAX_INDEX; t++)
			{
				uint8 ui8CardData = m_GameLogic->SwitchToCardData(t);
				CChiHuRight chr;
				if (WIK_CHI_HU == AnalyseHuCard(vecCardIndexTemp, vecWeave, ui8CardData, chr))
				{
					return WIK_LISTEN;
				}
			}
		}

		return mapTingPaiList.size() ? WIK_LISTEN : WIK_NULL;
	}

	uint8 AIMaJiangChannelBaseInterface::AnalyseTingCard(const uint8 & ui8PlayerPosID)
	{
		std::vector<uint8 > vecCardIndexTemp = m_ui8UserCardIndex[ui8PlayerPosID];

		std::map<uint8, std::vector<uint8> > & mapTingPaiList = m_MPlayerTingCardList[ui8PlayerPosID];
		mapTingPaiList.clear();

		uint8  ui8CardNumCount = m_GameLogic->GetCardCount(vecCardIndexTemp);

		uint8  ui8MgicCardNum = m_GameLogic->GetMagicCardNum(vecCardIndexTemp);

		if (ui8MgicCardNum > 1) return WIK_NULL;
		if ((ui8CardNumCount - 2) % 3 == 0)
		{//摸牌后出牌是否能听牌
			for (uint8 i = 0; i < MAX_INDEX; i++)
			{
				if (vecCardIndexTemp[i] == 0) continue;
				if (vecCardIndexTemp[i] >= m_vecNoOutCardsIndex[ui8PlayerPosID][i] && m_vecNoOutCardsIndex[ui8PlayerPosID][i] != 0) continue;
				vecCardIndexTemp[i]--;
				std::vector<uint8 > resultTemp;
				for (uint8 t = 0; t < MAX_INDEX; t++)
				{
					if (m_GameLogic->IsMagicCard(t)) continue;
					CChiHuRight chr;
					uint8 ui8CardData = m_GameLogic->SwitchToCardData(t);
					uint32 __time = now();
					if (WIK_CHI_HU == AnalyseHuCard(ui8PlayerPosID, vecCardIndexTemp, m_WeaveItemArray[ui8PlayerPosID], ui8CardData, chr))
					{
						resultTemp.push_back(m_GameLogic->SwitchToCardData(t));
						if (ui8MgicCardNum > 1) return WIK_LISTEN;
					}
					if (now() - __time > 1000)
					{
						String str = "";
						for (uint8 y = 0; y < MAX_INDEX; y++)
						{
							if (vecCardIndexTemp[y])
							{
								for (uint8 k = 0; k < vecCardIndexTemp[y]; k++)
								{
									str += StringConverter::toString(y) + ",";
								}
							}
						}
						Log.Success("AIMaJiangChannelBaseInterface::AnalyseTingCard", "str:%s ui8CardData:%d", str.c_str(), ui8CardData);
					}
				}
				if (resultTemp.size())
					mapTingPaiList.insert(std::make_pair(m_GameLogic->SwitchToCardData(i), resultTemp));
				vecCardIndexTemp[i]++;
			}
		}
		else
		{//查叫是否听牌
			for (uint8 t = 0; t < MAX_INDEX; t++)
			{
				uint8 ui8CardData = m_GameLogic->SwitchToCardData(t);
				CChiHuRight chr;
				if (WIK_CHI_HU == AnalyseHuCard(ui8PlayerPosID, m_ui8UserCardIndex[ui8PlayerPosID], m_WeaveItemArray[ui8PlayerPosID], ui8CardData, chr))
				{
					mapTingPaiList[t].push_back(0);
				}
			}
		}

		return mapTingPaiList.size() ? WIK_LISTEN : WIK_NULL;
	}

	//玩家操作
	bool AIMaJiangChannelBaseInterface::UserOperateCard(const uint8 & ui8PlayerPosID, const uint8 & ui8OperateCard, const uint8 & ui8OperateCode, std::vector<uint8 > ui8CardData)
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", "ui8PlayerPosID[%d] ui8OperateCard[%d] ui8OperateCode[%d]",
			ui8PlayerPosID,
			ui8OperateCard,
			ui8OperateCode);
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", "m_ui8CurrentPos[%d] ",
			m_ui8CurrentPos);
		if (m_run_status != en_MJChannelState_OperatorCard) return true;
		if (ui8PlayerPosID != m_ui8CurrentPos && m_ui8CurrentPos != INVALID_uint8)
		{
			WorldPacket	packet;
			if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_TimeError))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			return true;
		}
		if (m_ui8CurrentPos == INVALID_uint8)
		{//其他玩家打牌后提供的操作
			if (m_bResponse[ui8PlayerPosID] == true)
			{
				WorldPacket	packet;
				if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_Repeate))
					SendProtocolToPlayer(&packet, ui8PlayerPosID);
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", "m_bResponse[ui8PlayerPosID] == true ");
				return true;
			}
			if (ui8OperateCode != WIK_NULL && (m_ui8UserAction[ui8PlayerPosID] & ui8OperateCode) == 0)
			{
				WorldPacket	packet;
				if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_Error))
					SendProtocolToPlayer(&packet, ui8PlayerPosID);
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " NO ACTION ");
				return true;
			}

			if (ui8OperateCode == WIK_CHI_HU)
			{
				if (m_bGuoShui[ui8PlayerPosID])
				{
					WorldPacket	packet;
					if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_Error))
						SendProtocolToPlayer(&packet, ui8PlayerPosID);
					m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " m_bGuoShui = true");
					return true;
				}
			}

			uint8	ui8TargetPos = ui8PlayerPosID;
			uint8	ui8TargetAction = ui8OperateCode;

			//------------优先级判断

			m_bResponse[ui8PlayerPosID] = true;
			m_ui8PerformAction[ui8PlayerPosID] = ui8OperateCode;
			m_ui8OperateCard[ui8PlayerPosID] = ui8OperateCard;
			m_ui8TargetCardData[ui8PlayerPosID] = ui8CardData;

			//在自己未摸下一张牌的一圈内,不能弃上一家而胡下一家
			if (ui8TargetAction == WIK_NULL && (WIK_CHI_HU&m_ui8UserAction[ui8TargetPos]) &&
				m_ui8ProvidePos != ui8TargetPos)
			{
				m_bEnjoinChiHu[ui8TargetPos] = true;
				m_vecLouHuCards[ui8TargetPos].push_back(m_ui8ProvideCard);
			}
			OperateGuo(ui8PlayerPosID, ui8OperateCard, m_ui8UserAction[ui8PlayerPosID]);

			//判断
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				//获取玩家动作
				uint8 pos = (ui8PlayerPosID + i + m_nMaxPlayerNum) % m_nMaxPlayerNum;
				uint8 ui8UserAction = (m_bResponse[pos] == false) ? m_ui8UserAction[pos] : m_ui8PerformAction[pos];

				//获取优先级
				uint8	ui8UserActionRank = GetUserActionRank(ui8UserAction, pos, ui8TargetPos, m_ui8ProvidePos, ui8CardData);
				uint8	ui8TargetActionRank = GetUserActionRank(ui8TargetAction, ui8TargetPos, pos, m_ui8ProvidePos, ui8CardData);

				//判断并更新最高优先级
				if (ui8UserActionRank > ui8TargetActionRank)
				{
					ui8TargetPos = pos;
					ui8TargetAction = ui8UserAction;
				}
			}
			//			Log.Debug("AIMaJiangChannelBaseInterface::UserOperateCard", "1");
			//优先级最高的玩家是否已经操作过
			if (m_bResponse[ui8TargetPos] == false)
			{
				WorldPacket	packet;
				if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_Wite))
					SendProtocolToPlayer(&packet, ui8PlayerPosID);
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d", ui8TargetPos);
				return true;
			}

			bool isEnd = false;

			//等待所有能胡牌的人胡牌

			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				if (m_ChiHuRight[i].IsEmpty() == false && m_bPlayStatus[i] == true)
				{
					isEnd = true;
				}
			}


			m_next_run_status = en_MJChannelState_GiveCard;



			//没有更高优先级的操作并且放弃
			if (ui8TargetAction == WIK_NULL)
			{
				VecInit<uint8>(m_bResponse, m_nMaxPlayerNum, false);
				VecInit<uint8>(m_ui8UserAction, m_nMaxPlayerNum, 0);
				VecInit<uint8>(m_ui8OperateCard, m_nMaxPlayerNum, 0);
				VecInit<uint8>(m_ui8PerformAction, m_nMaxPlayerNum, 0);

				if (m_ui8GangPlayer != INVALID_uint8)
				{
					m_ui8CurrentPos = m_ui8GangPlayer;
					m_ui8SendCardPos = INVALID_uint8;
					m_next_run_status = en_MJChannelState_GiveCard;
					SelfGang(m_ui8GangPlayer, m_ui8GangCard, ui8CardData, false);
					m_ui8GangPlayer = INVALID_uint8;
					return true;
				}
				if (m_ui8AllPlayerOperatorStatus == enAllPlayerOperatorStatus_HaveOperator)
				{
					if (isEnd)
					{
						m_ui8AllPlayerOperatorStatus = enAllPlayerOperatorStatus_AllPlayerOperator;
						BeforeGameOverCalc();
					}
				}
				return true;
			}

			uint8 ui8TargetCard = m_ui8OperateCard[ui8TargetPos];

			m_ui8OutCardData = 0;
			m_bSendStatus = true;
			m_ui8OutCardPos = INVALID_uint8;
			m_bEnjoinChiHu[ui8TargetPos] = false;
			m_vecLouHuCards[ui8TargetPos].clear();


			//胡牌
			uint8 ui8LastHuUser = INVALID_uint8;

			tagWeaveItem WeaveItem;
			WeaveItem.ui8CenterCard = ui8TargetCard;
			WeaveItem.ui8ProvidePos = m_ui8ProvidePos;
			std::vector<uint8>  vecOperateCardList;
			if (ui8TargetAction != WIK_CHI_HU)
			{
				if (ui8TargetAction == WIK_LEFT)
				{
					uint8 ui8Card = m_ui8ProvideCard;
					std::vector<uint8> CardData;
					if (ui8Card - 1 == ui8TargetCard)
					{
						CardData.push_back(ui8TargetCard);
						CardData.push_back(ui8TargetCard + 2);
					}
					else if (ui8Card == ui8TargetCard)
					{
						CardData.push_back(ui8TargetCard + 1);
						CardData.push_back(ui8TargetCard + 2);
					}
					else if (ui8Card - 2 == ui8TargetCard)
					{
						CardData.push_back(ui8TargetCard);
						CardData.push_back(ui8TargetCard + 1);
					}
					m_ui8TargetCardData[ui8TargetPos] = CardData;
					ui8CardData = CardData;
				}
				if (ui8CardData.size())
				{
					vecOperateCardList = ui8CardData;
					RemoveCard(ui8TargetPos, m_ui8TargetCardData[ui8TargetPos]);
				}
				else
					vecOperateCardList = RemoveCardByAction(ui8TargetPos, ui8TargetAction, ui8TargetCard);
				WeaveItem.bHasScore = true;
				WeaveItem.ui8Type = 1;
				WeaveItem.ui8WeaveKind = ui8TargetAction;
				uint8 ui8CardNum = 3;
				/*if (WeaveItem.ui8WeaveKind == WIK_LEFT)
				{
					WeaveItem.ui8CardData[0] = WeaveItem.ui8CenterCard;
					WeaveItem.ui8CardData[1] = WeaveItem.ui8CenterCard + 1;
					WeaveItem.ui8CardData[2] = WeaveItem.ui8CenterCard + 2;
				}
				else if (WeaveItem.ui8WeaveKind == WIK_PENG)
				{
					WeaveItem.ui8CardData[0] = WeaveItem.ui8CenterCard;
					WeaveItem.ui8CardData[1] = WeaveItem.ui8CenterCard;
					WeaveItem.ui8CardData[2] = WeaveItem.ui8CenterCard;
				}
				else */if (WeaveItem.ui8WeaveKind == WIK_GANG)
				{
					ui8CardNum = 4;
				
				}
				for (uint8 i = 0; i < ui8CardNum; i++)
				{
					WeaveItem.ui8CardData[i] = vecOperateCardList[i];
				}
			}

			MJBaseTablePlayer * pTp = GetTablePlayerByPos(ui8PlayerPosID);

			if (m_WeaveItemArray[ui8TargetPos].size() > MAX_WEAVE)
			{
				Log.Error("AIMaJiangChannelBaseInterface::UserOperateCard", "m_ui8WeaveItemCount[%d] :%d", ui8TargetPos, m_WeaveItemArray[ui8TargetPos].size());
				ASSERT(0);
			}
			if (ui8TargetAction == WIK_LEFT)
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d WIK_LEFT", ui8TargetPos);
				OperateChi(ui8TargetPos, WeaveItem);
				m_WeaveItemArray[ui8TargetPos].push_back(WeaveItem);
			}
			else if (ui8TargetAction == WIK_PENG)
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d WIK_PENG", ui8TargetPos);
				OperatePeng(ui8TargetPos, WeaveItem);

				m_WeaveItemArray[ui8TargetPos].push_back(WeaveItem);
			}
			else if (ui8TargetAction == WIK_GANG)
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d WIK_GANG", ui8TargetPos);
				OperateGang(ui8TargetPos, WeaveItem);
				m_bGangStatus = true;
				m_bGangOutStatus = true;
				m_bGangKai = true;
				m_WeaveItemArray[ui8TargetPos].push_back(WeaveItem);

				WorldPacket packet;
				/*if (sProtocolsMgr.CreateOperatePengGangPacket(&packet, ui8TargetPos, m_WeaveItemArray[ui8TargetPos][ui8Index]))
					BroadcastPacket(&packet);*/
					//回放记录
				PlayBack(&packet);
				pTp->mingGangNum++;
			}
			else if (ui8TargetAction == WIK_CHI_HU)
			{
				OperateHu(ui8TargetPos, m_ui8ProvidePos, ui8TargetCard);
				m_ui8ChiHuCard = ui8TargetCard;
				//胡牌判断
				

				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d  ui8TargetCard:%d WIK_CHI_HU", ui8TargetPos, ui8TargetCard);
				m_ui32ChiHuKind[ui8TargetPos] = AnalyseHuCard(ui8TargetPos, m_ui8UserCardIndex[ui8TargetPos],
					m_WeaveItemArray[ui8TargetPos],
					ui8TargetCard,
					m_ChiHuRight[ui8TargetPos]);
				if(ui8TargetCard != 0)
					m_ui8UserCardIndex[ui8TargetPos][m_GameLogic->SwitchToCardIndex(ui8TargetCard)]++;

				if (m_ui32ChiHuKind[ui8TargetPos] != WIK_NULL)
				{
					m_ui8YiPaoDuoXiangList[ui8TargetPos] = 1;

				}
				if (m_bGangOutStatus)
				{

				}
				if (m_bGangStatus)
				{
					m_ui8QiangGangProvidePos = m_ui8ProvidePos;
					m_ui8QiangGangProvideCard = m_ui8ChiHuCard;
					/*	next_run_status = en_ChannelRun_CalcWait;
					return  true;*/
				}
				m_bPlayStatus[ui8TargetPos] = false;
				if (m_nGameModeFlag == enMJGameMode_SCMJ_XLCH)
				{
					m_bPlayStatus[ui8TargetPos] = true;
				}
			}
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				if (m_ChiHuRight[i].IsEmpty() == false && m_bPlayStatus[i] == true)
				{
					Log.Debug("AIMaJiangChannelBaseInterface::UserOperateCard", "m_bPlayStatus[%d]:%d", i, m_bPlayStatus[i]);
					isEnd = true;
				}
			}
			if (m_GameLogic->AllowedYiPaoDuoXiang())
			{//一炮多响
				if (IsEstimateYiPaoDuoXiang() && m_GameLogic->IsYiPaoDuoXiangOperate(ui8TargetAction))
				{

					for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
					{
						bool isOp = m_GameLogic->IsYiPaoDuoXiangOperate(m_ui8UserAction[i]);
						m_GameLogic->LogDeBug("YiPaoDuoXiang", "i:%d  isOp:%d m_bResponse[i]:%d m_ui8UserAction[i]:%d", i, isOp, m_bResponse[i], m_ui8UserAction[i]);
						if (m_bResponse[i] == false && isOp)
						{
							m_ui8AllPlayerOperatorStatus = enAllPlayerOperatorStatus_HaveOperator;
							break;
						}
						else if ((m_bResponse[i] == true && (i == m_nMaxPlayerNum - 1)) || (isOp == false && (i == m_nMaxPlayerNum - 1)))
						{
							m_ui8AllPlayerOperatorStatus = enAllPlayerOperatorStatus_AllPlayerOperator;
							isEnd = true;
						}
					}
					//一炮多响 判断所有能胡的都胡了就结束
					if (m_ui8AllPlayerOperatorStatus == enAllPlayerOperatorStatus_AllPlayerOperator)
					{
						if (isEnd)
							BeforeGameOverCalc();
					}
					else if (m_ui8AllPlayerOperatorStatus == enAllPlayerOperatorStatus_HaveOperator)
					{
						return true;
					}
					return true;
				}
				else
				{
					if (ui8TargetAction == WIK_CHI_HU)
					{
						m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d WIK_CHI_HU END", ui8TargetPos);
						WorldPacket packet;
						if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_OK))
							SendProtocolToPlayer(&packet, ui8PlayerPosID);
						BeforeGameOverCalc();
						return true;
					}
				}
			}
			else
			{
				if (ui8TargetAction == WIK_CHI_HU)
				{
					m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOperateCard", " ui8TargetPos = %d WIK_CHI_HU END", ui8TargetPos);
					WorldPacket packet;
					if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_OK))
						SendProtocolToPlayer(&packet, ui8PlayerPosID);
					BeforeGameOverCalc();
					return true;
				}
			}

			VecInit<uint8>(m_bResponse, m_nMaxPlayerNum, false);
			VecInit<uint8>(m_ui8UserAction, m_nMaxPlayerNum, 0);
			VecInit<uint8>(m_ui8OperateCard, m_nMaxPlayerNum, 0);
			VecInit<uint8>(m_ui8PerformAction, m_nMaxPlayerNum, 0);
			std::vector<uint8>  m_ui8TargetCardDataTemp;
			VecInit<std::vector<uint8> >(m_ui8TargetCardData, m_nMaxPlayerNum, m_ui8TargetCardDataTemp);

			WorldPacket packet;
			if (ui8TargetAction != WIK_CHI_HU && ui8TargetAction != WIK_NULL)
			{
				if (sProtocolsMgr.CreateMJOperatePengGangPacket(&packet, ui8TargetPos, WeaveItem, m_ui8ProvideCard))
					BroadcastPacket(&packet);
				PlayBack(&packet);
			}


			//	回放记录
			if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_OK))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			m_ui8CurrentPos = ui8TargetPos;

			if (isEnd)
				BeforeGameOverCalc();
			if (ui8TargetAction == WIK_LEFT)
			{
				/*if (sProtocolsMgr.CreateMJCastCardNotify(&packet, ui8PlayerPosID, m_nCastHandCardTime))
					BroadcastPacket(&packet, ui8PlayerPosID);


				setStatusEndTimer(m_nAGiveHandCardTime);*/



				m_next_run_status = en_MJChannelState_CastCard;

			}
			else if (ui8TargetAction == WIK_PENG)
			{
				/*	if (sProtocolsMgr.CreateMJCastCardNotify(&packet, ui8PlayerPosID, m_nCastHandCardTime))
						BroadcastPacket(&packet, ui8PlayerPosID);
					setStatusEndTimer(m_nAGiveHandCardTime);*/
					//听牌

				m_next_run_status = en_MJChannelState_CastCard;

			}
			else if (ui8TargetAction == WIK_GANG)
			{
				m_next_run_status = en_MJChannelState_GiveCard;
			}
			return true;
		}
		else if (m_ui8CurrentPos == ui8PlayerPosID)
		{//玩家摸牌后提供的操作

			//无操作或操作无效
			if ((m_ui8UserAction[ui8PlayerPosID] & ui8OperateCode) == 0 && ui8OperateCode != 0)
			{
				/*WorldPacket	packet;
				if (sProtocolsMgr.CreateOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_Error))
					SendProtocolToChaidId(ui8PlayerPosID, &packet);*/
				return false;
			}
			if (m_GameLogic->IsValidCard(ui8OperateCard) == false && ui8OperateCode != 0)
			{
				Log.Error("AIMaJiangChannelBaseInterface::UserOperateCard", "ui8OperateCard error :%d ui8PlayerPosID:%d ui8OperateCode:%d", ui8OperateCard, ui8PlayerPosID, ui8OperateCode);
				ASSERT(0);
				return false;
			}
			m_bAnyOperate = true;
			m_bSendStatus = true;
			m_bEnjoinChiHu[m_ui8CurrentPos] = false;
			m_vecLouHuCards[m_ui8CurrentPos].clear();

			m_ui8UserAction[m_ui8CurrentPos] = WIK_NULL;
			m_ui8PerformAction[m_ui8CurrentPos] = WIK_NULL;

			bool bPublic = true;
			switch (ui8OperateCode)
			{
			case WIK_GANG:
			{
				m_bGangKai = true;
				m_ui8CurrentPos = ui8PlayerPosID;
				m_ui8SendCardPos = INVALID_uint8;
				SelfGang(ui8PlayerPosID, ui8OperateCard, ui8CardData, m_bQiangGangHu);
				break;
			}
			case WIK_CHI_HU:
			{

				OperateHu(ui8PlayerPosID, ui8PlayerPosID, m_uint8SendCardData);
				m_ui8ProvidePos = m_ui8CurrentPos;

				m_ui8ProvideCard = m_uint8SendCardData;

				m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8PlayerPosID], m_ui8ProvideCard);
				m_ui32ChiHuKind[ui8PlayerPosID] = AnalyseHuCard(ui8PlayerPosID, m_ui8UserCardIndex[ui8PlayerPosID],
					m_WeaveItemArray[ui8PlayerPosID],
					m_ui8ProvideCard,
					m_ChiHuRight[ui8PlayerPosID]);

				m_ui8ChiHuCard = m_ui8ProvideCard;

				m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(m_ui8ProvideCard)]++;
				m_bPlayStatus[ui8PlayerPosID] = false;
				if (m_nGameModeFlag == enMJGameMode_SCMJ_XLCH)
				{
					m_bPlayStatus[ui8PlayerPosID] = true;
				}
				BeforeGameOverCalc();
				break;
			}
			case WIK_LISTEN:
			{
				m_bBaoJiao[m_ui8CurrentPos] = true;
				m_ui8Trustee[m_ui8CurrentPos] = enPlayer_AutoHuPai;
				OperateListen(ui8PlayerPosID, ui8OperateCard);
				std::vector<uint8> mTemp;
				mTemp = m_MPlayerTingCardList[ui8PlayerPosID][ui8OperateCard];
				m_MPlayerTingCardList[ui8PlayerPosID].clear();
				m_MPlayerTingCardList[ui8PlayerPosID][ui8OperateCard] = mTemp;

				WorldPacket packet;
				if (sProtocolsMgr.CreateMJOperateListenPacket(&packet, ui8PlayerPosID))
					BroadcastPacket(&packet);

				UserOutCard(ui8PlayerPosID, ui8OperateCard);
				break;

			}
			case WIK_NULL:
				m_next_run_status = en_MJChannelState_CastCard;
			}

		}
		WorldPacket	packet;
		if (sProtocolsMgr.CreateMJOperatePacket(&packet, ui8OperateCode, ui8OperateCard, enUserOperate_OK))
			SendProtocolToPlayer(&packet, ui8PlayerPosID);
		return false;
	}
	//玩家操作
	bool AIMaJiangChannelBaseInterface::UserOperateCard(CharPtr & pChr, const uint8 & ui8OperateCard, const uint8 & ui8OperateCode, std::vector<uint8 > ui8CardData)
	{
		if (pChr.isNull())  return false;
		WGS_MJCHANNEL_LOCK;
		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());
		if (pTp == NULL) return false;

		return UserOperateCard(pTp->pos, ui8OperateCard, ui8OperateCode, ui8CardData);
	}

	//摸牌者杠牌
	void AIMaJiangChannelBaseInterface::SelfGang(const uint8 & ui8PlayerPosID, const uint8 & ui8OperateCard, std::vector<uint8> ui8CardData, bool bQiangGang)
	{
		uint8 ui8OperatorIndex = m_GameLogic->SwitchToCardIndex(ui8OperateCard);
		std::vector<uint8 >  ui8MagicCards = m_GameLogic->GetMagicCard(m_ui8UserCardIndex[ui8PlayerPosID]);
		uint8 _index = INVALID_uint8;
		tagWeaveItem temp;
		MJBaseTablePlayer * pTp = GetTablePlayerByPos(ui8PlayerPosID);
		for (uint8 i = 0; i < m_WeaveItemArray[ui8PlayerPosID].size(); i++)
		{
			if (m_WeaveItemArray[ui8PlayerPosID][i].ui8WeaveKind == WIK_PENG && m_WeaveItemArray[ui8PlayerPosID][i].ui8CenterCard == ui8OperateCard)
			{
				if (bQiangGang)
				{
					m_GameLogic->LogDeBug(" AIMaJiangChannelBaseInterface::SelfGang", "Check QiangGang ui8OperateCard：%d", ui8OperateCard);
					if (EstimateUserQiangGang(ui8PlayerPosID, ui8OperateCard))
					{
						m_bGangStatus = true;
						m_ui8GangPlayer = ui8PlayerPosID;
						m_ui8GangCard = ui8OperateCard;
						m_ui8GangCardData = ui8CardData;
						return;
					}
				}
				uint8 ui8AddCard = ui8OperatorIndex;
				if (m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex] > 0)
				{
					m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex]--;
				}
				else if (ui8MagicCards.size() > 0)
				{
					ui8AddCard = ui8MagicCards.front();
					m_ui8UserCardIndex[ui8PlayerPosID][ui8AddCard]--;
				}  
				else
				{
					Log.Error("AIMaJiangChannelBaseInterface::SelfGang", "Gang Error");
					ASSERT(false);
				}
				_index = i;
				temp = m_WeaveItemArray[ui8PlayerPosID][i];
				temp.ui8WeaveKind = WIK_GANG;
				temp.ui8Type = enGangType_MianXiaGang;
				temp.ui8ProvidePos = ui8PlayerPosID;
				temp.ui8CardData[3] = m_GameLogic->SwitchToCardData(ui8AddCard);
				break;
			}
		}

		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::SelfGang", "_index:%d", _index);
		if (_index >= m_WeaveItemArray[ui8PlayerPosID].size())
		{
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::SelfGang", "m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex]:%d", m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex]);
			if (m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex] + ui8MagicCards.size() >= 4)
			{
				temp.bHasScore = true;
				temp.ui8CenterCard = ui8OperateCard;
				temp.ui8ProvidePos = ui8PlayerPosID;
				temp.ui8Type = enGangType_AnGang;
				temp.ui8WeaveKind = WIK_GANG;
			/*	temp.ui8CardData[0] = ui8OperateCard;
				temp.ui8CardData[1] = ui8OperateCard;
				temp.ui8CardData[2] = ui8OperateCard;
				temp.ui8CardData[3] = ui8OperateCard;
				m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex] = 0;
				/*temp.ui8CardData[0] = ui8CardData[0];
				temp.ui8CardData[1] = ui8CardData[1];
				temp.ui8CardData[2] = ui8CardData[2];
				temp.ui8CardData[3] = ui8CardData[3];*/
				RemoveCard(ui8PlayerPosID, ui8CardData);
				int ui8NumTemp = m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex];
				for (uint8 t = 0; t < 4; t++)
				{
					if (ui8NumTemp-- > 0)
					{
						temp.ui8CardData[t] = m_GameLogic->SwitchToCardData(ui8OperatorIndex);
						m_ui8UserCardIndex[ui8PlayerPosID][ui8OperatorIndex]--;
					}
					else
					{
						temp.ui8CardData[t] = m_GameLogic->SwitchToCardData(ui8MagicCards.front());
						m_ui8UserCardIndex[ui8PlayerPosID][ui8MagicCards.front()]--;
						ui8MagicCards.erase(ui8MagicCards.begin());
					}
				}
			}
		}

		OperateGang(ui8PlayerPosID, temp);
		if (_index != INVALID_uint8 && _index < m_WeaveItemArray[ui8PlayerPosID].size())
		{
			m_WeaveItemArray[ui8PlayerPosID][_index] = temp;
			pTp->buGangNum++;
		}
		else
		{
			m_WeaveItemArray[ui8PlayerPosID].push_back(temp);
			pTp->anGangNum++;
		}

		WorldPacket packet;
		if (sProtocolsMgr.CreateMJOperatePengGangPacket(&packet, ui8PlayerPosID, temp, m_ui8ProvideCard))
			BroadcastPacket(&packet);
		//回放记录
		PlayBack(&packet);

		m_next_run_status = en_MJChannelState_GiveCard;
	}

	//出牌响应
	bool AIMaJiangChannelBaseInterface::EstimateUserRespond(const uint8 & ui8CurrentPos, const uint8 & ui8CenterCard, const uint8 & EstimatKind)
	{
		VecInit<uint8>(m_bResponse, m_nMaxPlayerNum, false);
		VecInit<uint8>(m_ui8UserAction, m_nMaxPlayerNum, 0);
		VecInit<uint8>(m_ui8PerformAction, m_nMaxPlayerNum, 0);

		bool isAnyAction = false;

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (i == ui8CurrentPos || m_bPlayStatus[i] == false) continue;
			Log.Debug("AIMaJiangChannelBaseInterface::EstimateUserRespond", "i: %d", i);

			//吃
			if (m_GameLogic->AllowedChi())
			{
				bool bChiPai = false;
				if (m_GameLogic->GetChiPaiMode() == enChiPaiMode_ShangJia)
				{
					if ((i + m_nMaxPlayerNum FX - 1) % m_nMaxPlayerNum == ui8CurrentPos)
					{
						bChiPai = true;
					}
				}
				else if (m_GameLogic->GetChiPaiMode() == enChiPaiMode_DuiJia)
				{
					if ((i + m_nMaxPlayerNum FX + 1) % m_nMaxPlayerNum != ui8CurrentPos)
					{
						bChiPai = true;
					}
				}
				if (bChiPai)
				{
					if (IsEstimateChi(ui8CurrentPos, i, ui8CenterCard))
					{
						Log.Debug("AIMaJiangChannelBaseInterface::EstimateUserRespond", "%d %d", (i + m_nMaxPlayerNum FX - 1) % m_nMaxPlayerNum, ui8CurrentPos);
						if (m_bBaoJiao[i] != true)
						{
							uint8 result = m_GameLogic->EstimateChiCard(m_ui8UserCardIndex[i], ui8CenterCard, m_VPlayerChiCardList[i]);
							m_ui8UserAction[i] |= result;
							if (result != WIK_NULL)
								isAnyAction = true;
						}
					}
				}

			}
			//碰
			if (m_GameLogic->AllowedPeng())
			{
				if (IsEstimatePeng(ui8CurrentPos, i, ui8CenterCard))
				{
					if (m_bBaoJiao[i] != true)
					{
						uint8 result = m_GameLogic->EstimatePengCard(m_ui8UserCardIndex[i], ui8CenterCard, m_VPlayerPengCardList[i]);
						m_ui8UserAction[i] |= result;
						if (result != WIK_NULL)
							isAnyAction = true;
					}
				}
			}

			//杠
			if (m_GameLogic->AllowedGang() && m_uint8LeftCardCount > 0)
			{
				if (IsEstimateGang(ui8CurrentPos, i, ui8CenterCard))
				{
					uint8 result = m_GameLogic->EstimateGangCard(m_ui8UserCardIndex[i], ui8CenterCard, m_VPlayerGangCardList[i]);
					if (result != WIK_NULL)
					{
						if (m_bBaoJiao[i] == true || m_ui8Trustee[i] == enPlayer_AutoHuPai)
						{
							if (TingEstimateGang(i, ui8CenterCard))
							{
								isAnyAction = true;
								m_ui8UserAction[i] |= result;
							}
							else
								m_VPlayerGangCardList[i].clear();
						}
						else
						{
							m_ui8UserAction[i] |= result;
							isAnyAction = true;
						}
					}
				}
			}

			//胡牌判断
			if (m_GameLogic->AllowedDianPaoHu())
			{
				if (IsEstimateHu(ui8CurrentPos, i, ui8CenterCard) && m_bEnjoinChiHu[i] == false)
				{
					CChiHuRight ChiHuRight;
					uint8 result = AnalyseHuCard(i, m_ui8UserCardIndex[i], m_WeaveItemArray[i], ui8CenterCard, ChiHuRight);
					m_ui8UserAction[i] |= result;
					Log.Debug("AIMaJiangChannelBaseInterface::EstimateUserRespond", "%d:``Hu:result:%d", i, result);
					if (result != WIK_NULL)
					{
						isAnyAction = true;
					}
				}
			}
		}

		if (isAnyAction)
		{
			m_ui8ProvidePos = ui8CurrentPos;
			m_ui8ProvideCard = ui8CenterCard;
			m_ui8ResumePos = m_ui8CurrentPos;
			m_ui8CurrentPos = INVALID_uint8;
				Log.Success("AIMaJiangChannelBaseInterface::EstimateUserRespond", "m_ui8ProvidePos[%d] m_ui8ProvideCard[%x] m_ui8ResumeUser[%d] ",
					m_ui8ProvidePos,
					m_ui8ProvideCard,
					m_ui8CurrentPos);
			m_next_run_status = en_MJChannelState_OperatorCard;


			//		setStatusEndTimer(/*sXmlDataMgr.getTCMJconf("A_SendCard")- 1000*/ 0);
		}


		return isAnyAction;
	}

	//-----------------------------------------------------------------------
	HSMStateHandler	AIMaJiangChannelBaseInterface::ChangeChannelState(MJChannelState state)
	{
		m_run_status = state;
		switch (m_run_status)
		{
		case en_MJChannelState_Prep:				// 准备
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_prep);
		case en_MJChannelState_ChooseBanker:		// 准备
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_choosebanker);
		case en_MJChannelState_SendCards:			// 发牌
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_sendcards);
		case en_MJChannelState_SwapCards:			// 换牌
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_swapcards);
		case en_MJChannelState_ChooseQue:			// 定缺
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_chooseque);
		case en_MJChannelState_GiveCard:			// 摸牌
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_givecard);
		case en_MJChannelState_CastCard:			// 出牌
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_castcard);
		case en_MJChannelState_OperatorCard:		// 操作牌
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_operatorcard);
		case en_MJChannelState_GameOverCalc:		// 游戏结算
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_calc);
		case en_MJChannelState_Close:				// 牌桌结束
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_close);
		case en_MJChannelState_Custom:				//自定义状态
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_custom);
		case en_MJChannelState_SameIP:				//同ip
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_sameipcheck);
		case en_MJChannelState_SendCardsBuPai:				//补花
			return HSMStateHandler(AIMaJiangChannelBaseInterface::battle_sendcardsbupai);
			break;
		default:
			return 0;
		}

		return 0;
	}

	//初始话自定义状态函数
	void AIMaJiangChannelBaseInterface::InitPublicFun()
	{
		m_mapStateInit.clear();
		m_mapStateUpdate.clear();
	}

	void AIMaJiangChannelBaseInterface::SetChannelPublicFun(String _key)
	{
		WGS_MJCHANNEL_STATE_LOCK;
		if (m_mapStateInit.find(_key) == m_mapStateInit.end())
		{
			Log.Error("AIMaJiangChannelBaseInterface::SetChannelPublicFun", "Change custom state error,m_mapStateInit not find key:%s", _StateKey.c_str());
			ASSERT(false);
		}
		if (m_mapStateUpdate.find(_key) == m_mapStateUpdate.end())
		{
			Log.Error("AIMaJiangChannelBaseInterface::SetChannelPublicFun", "Change custom state error,m_mapStateUpdate not find key:%s", _StateKey.c_str());
			ASSERT(false);
		}
		_StateKey = _key;
		m_next_run_status = en_MJChannelState_Custom;
	}

	void AIMaJiangChannelBaseInterface::ChangeChannelPublicFun()
	{
		WGS_MJCHANNEL_STATE_LOCK;
		/*	String _StateKey;
			std::map<String, StateInit>  m_mapStateInit;
			std::map<String, StateUpdate>  m_mapStateUpdate;*/

		if (m_mapStateInit.find(_StateKey) == m_mapStateInit.end())
		{
			Log.Error("AIMaJiangChannelBaseInterface::ChangeChannelPublicFun", "Change custom state error,m_mapStateInit not find key:%s", _StateKey.c_str());
			ASSERT(false);
		}
		if (m_mapStateUpdate.find(_StateKey) == m_mapStateUpdate.end())
		{
			Log.Error("AIMaJiangChannelBaseInterface::ChangeChannelPublicFun", "Change custom state error,m_mapStateUpdate not find key:%s", _StateKey.c_str());
			ASSERT(false);
		}
		publicBattelStateInit = m_mapStateInit[_StateKey];
		publicBattelUpdate = m_mapStateUpdate[_StateKey];
	}

	void AIMaJiangChannelBaseInterface::RunPublicBattelStateInit()
	{
		WGS_MJCHANNEL_LOCK;

		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return;

		if (publicBattelStateInit != NULL)
			(this->*publicBattelStateInit)();
		else
		{
			Log.Error("AIMaJiangChannelBaseInterface::RunPublicBattelStateInit", "publicBattelStateInit = NULL");
			ASSERT(false);
		}
	}

	// 牌桌结束Init
	void AIMaJiangChannelBaseInterface::setChannelBattleClose(void)
	{
		// 设置牌桌删除状态，请求删除牌桌


		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
			{
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr.isNull() == false)
				{
					Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleClose", "channel[%d] char[%d] status:%d", m_Unit->getHandle(), pChr->getHandle(), pChr->getStatus());
					pChr->setStatus(CharacterStatusFree);
				}
			}
		}
		WorldPacket packet;
		if (sProtocolsMgr.CreateDissolveChannelPacket(&packet, m_nDissolveReson))
			BroadcastPacket(&packet);
		m_Unit->setUInt32Field("status", Channel::ChannelStatusDone);
		ChannelPtr pChn = sChannelMgr.getByHandle(m_Unit->getHandle());
		pChn->setWantRemove();

		// 清理玩家列表
	//	m_vSeatPlayers.clear();
		m_mapWatchPlayers.clear();
	}

	// 起手补牌Init
	void AIMaJiangChannelBaseInterface::setChannelBattleSendCardsBuPai(void)
	{
		WGS_MJCHANNEL_LOCK;
		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleSendCardsBuPai", "channel[%u] cb_id[%u] !", m_Unit->getHandle(), m_btLog.cb_id);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			m_vecStartBuPaiStatus[i] = enStartBuPai_Init;
		}
	//setStatusEndTimer(m_nSameIPCheckTimer);
	}

	void AIMaJiangChannelBaseInterface::setChannelBattleGiveCardBuPai(void)
	{
		WGS_MJCHANNEL_LOCK;
		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleGiveCardBuPai", "channel[%u] cb_id[%u] !", m_Unit->getHandle(), m_btLog.cb_id);
		setStatusEndTimer(m_GameLogic->GetChannelTime("ABuHuaTime"));
	}

	void AIMaJiangChannelBaseInterface::setChannelBattleSameIPCheck(void)
	{
		WGS_MJCHANNEL_LOCK;
		Log.Debug("AIMaJiangChannelBaseInterface::setChannelBattleSameIPCheck", "channel[%u] cb_id[%u] !", m_Unit->getHandle(), m_btLog.cb_id);
		std::vector<CharPtr > vChars;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			CharPtr pChr = sCharMgr.load(GetTablePlayerByPos(i)->player._handle);
			vChars.push_back(pChr);
		}
		sGLMgr.CheckHaveSameIpPlayers(vChars);
		m_bThinkSameIP = true;
		setStatusEndTimer(m_nSameIPCheckTimer);
	}



	HSMStateHandler AIMaJiangChannelBaseInterface::RunPublicBattelUpdate(void)
	{
		WGS_MJCHANNEL_LOCK;

		if (m_next_run_status == en_MJChannelState_GameOverCalc)
			return ChangeChannelState(m_next_run_status);

		if (publicBattelStateInit != NULL)
			return (this->*publicBattelUpdate)();
		else
		{
			Log.Error("AIMaJiangChannelBaseInterface::RunPublicBattelUpdate", "publicBattelUpdate = NULL");
			ASSERT(false);
		}
		return 0;
	}

	//听牌下的杠牌
	bool AIMaJiangChannelBaseInterface::TingEstimateGang(const uint8 & ui8CurrentPos, const uint8 & ui8CenterCard)
	{
		std::vector<tagWeaveItem> temp = m_WeaveItemArray[ui8CurrentPos];
		std::vector<uint8> Cards = m_ui8UserCardIndex[ui8CurrentPos];
		if (m_ui8UserCardIndex[ui8CurrentPos][m_GameLogic->SwitchToCardIndex(ui8CenterCard)] == 4 || m_ui8UserCardIndex[ui8CurrentPos][m_GameLogic->SwitchToCardIndex(ui8CenterCard)] == 3)
		{
			tagWeaveItem gangTemp;
			gangTemp.ui8CenterCard = ui8CenterCard;
			gangTemp.ui8WeaveKind = WIK_GANG;
			temp.push_back(gangTemp);
			Cards[m_GameLogic->SwitchToCardIndex(ui8CenterCard)] = 0;
		}
		else if (m_ui8UserCardIndex[ui8CurrentPos][m_GameLogic->SwitchToCardIndex(ui8CenterCard)] == 1)
		{
			bool bOk = false;
			for (uint8 i = 0; i < m_WeaveItemArray[ui8CurrentPos].size(); i++)
			{
				if (m_WeaveItemArray[ui8CurrentPos][i].ui8WeaveKind == WIK_PENG && m_WeaveItemArray[ui8CurrentPos][i].ui8CenterCard == ui8CenterCard)
				{
					bOk = true;
					break;
				}
			}
//			if(bOk)
				return bOk;
		}
		
		std::vector<uint8> TingList;
		if (m_vecPlayerTingPaiTiShi[ui8CurrentPos].size())
			TingList = m_vecPlayerTingPaiTiShi[ui8CurrentPos];
		else
		{
			Log.Error("AIMaJiangChannelBaseInterface::TingEstimateGang", "m_MPlayerTingCardList[%d].size == 0", ui8CurrentPos);
			return true;
		}

		bool result = true;
		for (uint8 i = 0; i < TingList.size(); i++)
		{
			CChiHuRight chr;
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::TingEstimateGang", "TingList[%d] %d  pos[%d] weave[%d]", i, TingList[i], ui8CurrentPos, temp.size());
			if (WIK_CHI_HU != AnalyseHuCard(ui8CurrentPos,Cards, temp, TingList[i], chr))
			{
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::TingEstimateGang", "False");

				result = false;
				break;
			}
		}

		return result;
	}

	//发送操作通知
	void AIMaJiangChannelBaseInterface::SendOperateNotify()
	{
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			//如果可执行动作不为空 则通知玩家
			if (m_ui8UserAction[i] != WIK_NULL)
			{
				CMD_OperateNotify OperateNotify;
				OperateNotify.m_MPlayerTingCardList = m_MPlayerTingCardList[i];
				OperateNotify.m_VPlayerChiCardList = m_VPlayerChiCardList[i];
				OperateNotify.m_VPlayerPengCardList = m_VPlayerPengCardList[i];
				OperateNotify.m_VPlayerGangCardList = m_VPlayerGangCardList[i];
				OperateNotify.ui8ResumePos = m_ui8ProvidePos;
				OperateNotify.ui32LeftTime = m_nOperatorCardTime;
				if(IsSpecialHu(i) && (m_ui8UserAction[i] & WIK_CHI_HU) == WIK_CHI_HU)
					OperateNotify.ui8ActionCard = 0;
				else
					OperateNotify.ui8ActionCard = m_ui8ProvideCard;

				if (m_bOutCardTingList)
				{
					if ((m_ui8UserAction[i] & WIK_LISTEN) != 0)
					{
						m_ui8UserAction[i] = m_ui8UserAction[i] ^ WIK_LISTEN;
						if (m_ui8UserAction[i] && OperateNotify.ui8ResumePos != i )
						{
							OperateNotify.m_MPlayerTingCardList.clear();
						}
						OperateNotify.ui8ResumePos = i;
					}
					else if (m_ui8UserAction[i])
					{
						OperateNotify.m_MPlayerTingCardList.clear();
					}
					
				}
				OperateNotify.ui8ActionMask = m_ui8UserAction[i];
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::SendOperateNotify", "i:%d Action:%d m_bOutCardTingList：%d", i, m_ui8UserAction[i], m_bOutCardTingList);
				WorldPacket packet;
				if (sProtocolsMgr.CreateMJOperateNotifyPacket(&packet, OperateNotify))
					SendProtocolToPlayer(&packet, i);
			}
		}
	}

	//根据动作类型移除手牌
	std::vector<uint8> AIMaJiangChannelBaseInterface::RemoveCardByAction(const uint8 & ui8TargetPos, const uint8 & ui8Action, const uint8 & ui8TargetCard)
	{
		std::vector<uint8> result;
		switch (ui8Action)
		{
		case WIK_LEFT:
		{
			uint8 ui8RemoveCard[3];
			m_GameLogic->GetWeaveCard(ui8Action, ui8TargetCard, ui8RemoveCard);
			m_GameLogic->RemoveCard(ui8RemoveCard, 3, &ui8TargetCard, 1);
			result = m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8TargetPos], ui8RemoveCard, 2);
			break;
		}
		case WIK_RIGHT:
		{
			uint8 ui8RemoveCard[3];
			m_GameLogic->GetWeaveCard(ui8Action, ui8TargetCard, ui8RemoveCard);
			m_GameLogic->RemoveCard(ui8RemoveCard, 3, &ui8TargetCard, 1);
			result = m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8TargetPos], ui8RemoveCard, 2);
			break;
		}
		case WIK_CENTER:
		{
			uint8 ui8RemoveCard[3];
			m_GameLogic->GetWeaveCard(ui8Action, ui8TargetCard, ui8RemoveCard);
			m_GameLogic->RemoveCard(ui8RemoveCard, 3, &ui8TargetCard, 1);
			result = m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8TargetPos], ui8RemoveCard, 2);
			break;
		}
		case WIK_PENG:
		{
			uint8 ui8RemoveCard[] = { ui8TargetCard ,ui8TargetCard };
			result = m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8TargetPos], ui8RemoveCard, 2);
			result.push_back(ui8TargetCard);
			break;
		}
		case WIK_GANG:
		{
			uint8 ui8RemoveCard[] = { ui8TargetCard ,ui8TargetCard ,ui8TargetCard };
			result = m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8TargetPos], ui8RemoveCard, CountArray(ui8RemoveCard));
			result.push_back(ui8TargetCard);
			break;
		}
		default:
			break;
		}
		return result;
	}

	//获取两个座位的位置关系
	uint8 AIMaJiangChannelBaseInterface::GetRelativePos(const uint8 & ui8PlayerPos, const uint8 & ui8TargetPos)
	{
		if (ui8PlayerPos > m_nMaxPlayerNum || ui8TargetPos > m_nMaxPlayerNum)
		{
			return INVALID_uint8;
		}
		if (ui8PlayerPos == ui8TargetPos)
		{
			return enPos_Self;
		}
		if ((ui8PlayerPos + m_nMaxPlayerNum FX 1) % m_nMaxPlayerNum == ui8TargetPos)
		{
			return enPos_Down;
		}
		if ((ui8PlayerPos + m_nMaxPlayerNum - FX 1) % m_nMaxPlayerNum == ui8TargetPos)
		{
			return enPos_Up;
		}
		if (abs(ui8PlayerPos - ui8TargetPos) == 2)
		{
			return enPos_Medium;
		}
		return INVALID_uint8;
	}

	//动作优先级
	uint8 AIMaJiangChannelBaseInterface::GetUserActionRank(uint8 ui8UserAction, uint8 ui8CureentUser, uint8 ui8TargetPos, uint8 ui8ProvidePos, std::vector<uint8 > ui8CardData)
	{
		if (ui8UserAction & WIK_CHI_HU) return 5;
		if (ui8UserAction & WIK_GANG) return 4;
		if (ui8UserAction & WIK_PENG) return 2;
		if (ui8UserAction & (WIK_RIGHT | WIK_CENTER | WIK_LEFT)) return 1;
		return 0;
	}

	//抢杠响应
	bool AIMaJiangChannelBaseInterface::EstimateUserQiangGang(const uint8 & ui8CurrentPos, const uint8 & ui8CenterCard)
	{
		bool isAnyAction = false;
		std::vector<uint8> ui8UserAction(m_nMaxPlayerNum, 0);

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (i == ui8CurrentPos || m_bPlayStatus[i] == false) continue;

			m_GameLogic->LogDeBug(" AIMaJiangChannelBaseInterface::EstimateUserQiangGang", "i:%d m_bEnjoinChiPeng[i]:%d IsEstimateHu(ui8CurrentPos,i, ui8CenterCard):%d", i, m_bEnjoinChiPeng[i], IsEstimateHu(ui8CurrentPos, i, ui8CenterCard));
			//碰杠牌判断
			if (m_bEnjoinChiPeng[i] == false && IsEstimateHu(ui8CurrentPos, i, ui8CenterCard))
			{


				m_GameLogic->LogDeBug(" AIMaJiangChannelBaseInterface::EstimateUserQiangGang", "m_bEnjoinChiHu[i]:%d", m_bEnjoinChiHu[i]);
				//胡牌判断
				if (m_bEnjoinChiHu[i] == false)
				{
					CChiHuRight ChiHuRight;
					uint8 result = AnalyseHuCard(i,
						m_ui8UserCardIndex[i], m_WeaveItemArray[i],
						ui8CenterCard,
						ChiHuRight);
					ui8UserAction[i] |= result;
					m_ui8UserAction[i] |= result;
					m_GameLogic->LogDeBug(" AIMaJiangChannelBaseInterface::EstimateUserQiangGang", "result[i]:%d", result);
					if (result != WIK_NULL)
					{
						isAnyAction = true;
					}
				}
			}

		}

		if (isAnyAction)
		{
			m_ui8ProvidePos = ui8CurrentPos;
			m_ui8ProvideCard = ui8CenterCard;
			m_ui8ResumePos = m_ui8CurrentPos;
			m_ui8CurrentPos = INVALID_uint8;
			m_next_run_status = en_MJChannelState_OperatorCard;
			setStatusEndTimer(0);
			m_bAnyOperate = true;

		}
		return isAnyAction;
	}

	//玩家出牌
	uint8 AIMaJiangChannelBaseInterface::UserOutCard(const uint8 & ui8PlayerPosID, const uint8 & ui8OutCardData, bool bUser)
	{

		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "ui8PlayerPosID:%d ui8OutCardData:%d", ui8PlayerPosID, ui8OutCardData);
		if (m_run_status != en_MJChannelState_CastCard && m_run_status != en_MJChannelState_OperatorCard)
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_NotCureentUser))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			return false;
		}

		if (ui8PlayerPosID != m_ui8CurrentPos)
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_NotCureentUser))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "UserOutCard_NotCureentUser ui8PlayerPosID:%d m_ui8CurrentPos:%d", ui8PlayerPosID, m_ui8CurrentPos);
			return false;
		}

		if (m_bPlayStatus[ui8PlayerPosID] == false)
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_NotCureentUser))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "m_bPlayStatus[%d]:%d", ui8PlayerPosID, m_bPlayStatus[ui8PlayerPosID]);
			return false;
		}
		if (!m_GameLogic->IsValidCard(ui8OutCardData))
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_OutCardDataError))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "ui8OutCardData:%d error", ui8OutCardData);

			return false;
		}

		if (m_vecNoOutCardsIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(ui8OutCardData)] >= m_ui8UserCardIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(ui8OutCardData)]
			&& m_vecNoOutCardsIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(ui8OutCardData)] != 0)
		{
			uint8 OutCard = m_GameLogic->SwitchToCardIndex(ui8OutCardData);
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "m_vecNoOutCardsIndex[%d]:%d m_ui8UserCardIndex[%d]:%d", OutCard,
				m_vecNoOutCardsIndex[ui8PlayerPosID][OutCard], OutCard, m_ui8UserCardIndex[ui8PlayerPosID][OutCard]);
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_OutCardNotFind))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			return false;
		}

		if (!m_GameLogic->RemoveCard(m_ui8UserCardIndex[ui8PlayerPosID], ui8OutCardData))
		{
			WorldPacket packet;
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_OutCardNotFind))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "No Card m_ui8UserCardIndex[%d]:%d", ui8PlayerPosID, m_GameLogic->GetCardCount(m_ui8UserCardIndex[ui8PlayerPosID]));
			return false;
		}

		m_bAnyOperate = true;
		m_bSendStatus = true;
		if (m_bGangStatus)
		{
			m_bGangStatus = false;
			m_bGangOutStatus = true;
		}
		m_bGangKai = false;
		m_ui8UserAction[ui8PlayerPosID] = WIK_NULL;
		m_ui8PerformAction[ui8PlayerPosID] = WIK_NULL;

		//出牌记录
		m_ui8OutCardCount++;
		m_ui8OutCardData = ui8OutCardData;
		m_ui8OutCardPos = ui8PlayerPosID;

		m_ui8ProvideCard = ui8OutCardData;
		m_ui8ProvidePos = ui8PlayerPosID;

		//用户切换
		do
		{
			m_ui8CurrentPos = (m_ui8CurrentPos + m_nMaxPlayerNum FX 1) % m_nMaxPlayerNum;
		} while (!m_bPlayStatus[m_ui8CurrentPos]);

		WorldPacket packet;
	/*	if (sProtocolsMgr.CreateMJOutCardForAllPlayerPacket(&packet, ui8PlayerPosID, ui8OutCardData))
			PlayBack(&packet);*/

		if (m_ui8Trustee[ui8PlayerPosID] != enPlayer_Normal || bUser == false)
		{
			if (sProtocolsMgr.CreateMJOutCardForAllPlayerPacket(&packet, ui8PlayerPosID, ui8OutCardData))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
		}
		else
		{
			if (sProtocolsMgr.CreateMJOutCardPacket(&packet, ui8OutCardData, UserOutCard_OK))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
		}

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (i == ui8PlayerPosID) continue;
			if (sProtocolsMgr.CreateMJOutCardForAllPlayerPacket(&packet, ui8PlayerPosID, ui8OutCardData))
				SendProtocolToPlayer(&packet, i);
		}
		m_next_run_status = en_MJChannelState_GiveCard;

		//听牌
		if (m_GameLogic->AllowedTingList())
		{
			WorldPacket packet;
			//if (m_MPlayerTingCardList[ui8PlayerPosID].size() && IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData) && m_GameLogic->AllowedTing())
			//{
			//	if (m_MPlayerTingCardList[ui8PlayerPosID].find(ui8OutCardData) != m_MPlayerTingCardList[ui8PlayerPosID].end())
			//	{
			//		if (m_MPlayerTingCardList[ui8PlayerPosID].begin()->second.front() == 0)
			//		{
			//			/*	AnalyseTingCard(ui8PlayerPosID);*/
			//			std::vector<uint8> temp;
			//			std::map<uint8, std::vector<uint8> >::iterator iter;
			//			for (iter = m_MPlayerTingCardList[ui8PlayerPosID].begin(); iter != m_MPlayerTingCardList[ui8PlayerPosID].end(); iter++)
			//			{
			//				temp.push_back(m_GameLogic->SwitchToCardData(iter->first));
			//			}
			//			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, temp))
			//				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
			//		}
			//		else
			//		{
			//			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, m_MPlayerTingCardList[ui8PlayerPosID][ui8OutCardData]))
			//				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = m_MPlayerTingCardList[ui8PlayerPosID][ui8OutCardData];
			//		}
			//	}
			//	else
			//	{
			//		if (m_MPlayerTingCardList[ui8PlayerPosID].begin()->second.front() == 0)
			//		{
			//			/*	AnalyseTingCard(ui8PlayerPosID);*/
			//			std::vector<uint8> temp;
			//			std::map<uint8, std::vector<uint8> >::iterator iter;
			//			for (iter = m_MPlayerTingCardList[ui8PlayerPosID].begin(); iter != m_MPlayerTingCardList[ui8PlayerPosID].end(); iter++)
			//			{
			//				temp.push_back(m_GameLogic->SwitchToCardData(iter->first));
			//			}
			//			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, temp))
			//				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
			//		}
			//		else if (m_MPlayerTingCardList[ui8PlayerPosID].begin()->second.front() != 0 && m_bBaoJiao[ui8PlayerPosID] == true)
			//		{
			//			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, m_MPlayerTingCardList[ui8PlayerPosID].begin()->second))
			//				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = m_MPlayerTingCardList[ui8PlayerPosID].begin()->second;
			//		}
			//		else
			//		{
			//			std::vector<uint8> temp;
			//			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, temp))
			//				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
			//		}

			//	}

			//}
			//else if (IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData) && m_GameLogic->AllowedTing())
			//{
			//	std::vector<uint8> temp;
			//	if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, temp))
			//		SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//	m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
			//}
			//else if (IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData))
			//{
			//	m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "ting list");

			//	AnalyseTingCard(ui8PlayerPosID);
			//	std::vector<uint8> temp;
			//	std::map<uint8, std::vector<uint8> >::iterator iter;
			//	for (iter = m_MPlayerTingCardList[ui8PlayerPosID].begin(); iter != m_MPlayerTingCardList[ui8PlayerPosID].end(); iter++)
			//	{
			//		temp.push_back(m_GameLogic->SwitchToCardData(iter->first));
			//	}
			//	if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, temp))
			//		SendProtocolToPlayer(&packet, ui8PlayerPosID);
			//	m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
			//}

			std::vector<uint8> temp = GetTingPaiList(ui8PlayerPosID, ui8OutCardData);
			if (sProtocolsMgr.CreateMJTingPaiListPacket(&packet, temp))
				SendProtocolToPlayer(&packet, ui8PlayerPosID);
			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;

		}

		EstimateUserRespond(ui8PlayerPosID, ui8OutCardData, 0);

		OperateOutCard(ui8PlayerPosID, ui8OutCardData);

		m_ui8SendCardPos = INVALID_uint8;
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::UserOutCard", "m_next_run_status:%d", m_next_run_status);

		return true;
	}



	bool AIMaJiangChannelBaseInterface::UserOutCard(CharPtr pChr, const uint8 & ui8OutCardData)
	{
		if (pChr.isNull()) return false;
		WGS_MJCHANNEL_LOCK;

		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());
		if (pTp == NULL) return false;
		return UserOutCard(pTp->pos, ui8OutCardData, true);
	}

	//自动操作
	void AIMaJiangChannelBaseInterface::AutoOperate(uint8 ui8PlayerPosID)
	{
		//if (m_ui8UserAction[ui8PlayerPosID] == WIK_NULL)
		//WaitALittle(500);
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::AutoOperate", "ui8PlayerPosID:%d", ui8PlayerPosID);
		//ASSERT(0);
		MJBaseTablePlayer * pTp = GetTablePlayerByPos(ui8PlayerPosID);

		CharPtr pChr = sCharMgr.load(pTp->player._handle);

		if (m_run_status == en_MJChannelState_CastCard)
		{
			if (m_ui8CurrentPos == ui8PlayerPosID)
			{
				uint8 temp1 = m_ui8CurrentPos, tempCard = AutoOutCardChoose(ui8PlayerPosID);
				UserOutCard(temp1, tempCard);
			}
			else
			{
				uint8 temp1 = m_ui8ProvideCard, temp2 = m_ui8OutCardData;
				if (m_ui8CurrentPos == INVALID_uint8)
					UserOperateCard(ui8PlayerPosID, temp2, WIK_NULL, std::vector<uint8>());
				else
					UserOperateCard(ui8PlayerPosID, temp1, WIK_NULL, std::vector<uint8>());
			}
			return;
		}

		if (m_ui8UserAction[ui8PlayerPosID] & WIK_CHI_HU)
		{
			uint8 temp1 = m_ui8ProvideCard/* , temp2 = m_ui8OutCardData */;
			uint8 ui8Operate = WIK_NULL;
			if (m_ui8Trustee[ui8PlayerPosID] == enPlayer_AutoHuPai)
				ui8Operate = WIK_CHI_HU;
			if (m_ui8CurrentPos == INVALID_uint8)
				UserOperateCard(ui8PlayerPosID, temp1, ui8Operate, std::vector<uint8>());
			else
				UserOperateCard(ui8PlayerPosID, temp1, ui8Operate, std::vector<uint8>());
		}

		else  if (m_ui8UserAction[ui8PlayerPosID] & WIK_GANG)
		{
			uint8 temp1 = m_ui8ProvideCard/* , temp2 = m_ui8OutCardData */;

			if (m_ui8CurrentPos == INVALID_uint8)
				UserOperateCard(ui8PlayerPosID, temp1, WIK_NULL, std::vector<uint8>());
			else
				UserOperateCard(ui8PlayerPosID, temp1, WIK_NULL, std::vector<uint8>());
		}
		else if (m_ui8CurrentPos == ui8PlayerPosID)
		{
			//	uint8 temp1 = m_ui8CurrentPos, tempCard = m_uint8SendCardData;
			uint8 temp1 = m_ui8CurrentPos;
			UserOperateCard(ui8PlayerPosID, temp1, WIK_NULL, std::vector<uint8>());
			/*if (m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)] == 0)
			{
				for (uint8 i = 0; i < MAX_INDEX; i++)
				{
					if (m_ui8UserCardIndex[temp1][i] != 0)
					{
						tempCard = m_GameLogic->SwitchToCardData(i);
						UserOutCard(temp1, tempCard);
						break;
					}
				}
			}
			else
				UserOutCard(temp1, tempCard);*/
		}
		else
		{
			uint8 temp1 = m_ui8ProvideCard;
			UserOperateCard(ui8PlayerPosID, temp1, WIK_NULL, std::vector<uint8>());
		}
	}

	//自动出牌选择
	uint8 AIMaJiangChannelBaseInterface::AutoOutCardChoose(uint8 ui8PlayerPosID)
	{
		uint8 tempCard = m_uint8SendCardData;
		uint8 temp1 = ui8PlayerPosID;
		MJBaseTablePlayer * pTp = GetTablePlayerByPos(ui8PlayerPosID);
		
			if (pTp)
			{
				if (pTp->ui8ChooseColor)
				{
					for (uint8 i = 0; i < MAX_INDEX; i++)
					{
						if (m_ui8UserCardIndex[temp1][i] != 0 && (m_vecNoOutCardsIndex[ui8PlayerPosID][i] < m_ui8UserCardIndex[temp1][i]))
						{
							tempCard = m_GameLogic->SwitchToCardData(i);
							if (m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)] == 0 || m_vecNoOutCardsIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(tempCard)] >= m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)])
								continue;
							if (m_GameLogic->GetCardColor(tempCard) != pTp->ui8ChooseColor)
								continue;
							
							return tempCard;
						}
					}
				}
			}

			if (m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)] != 0 && (m_vecNoOutCardsIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(tempCard)] < m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)]))
			{
				tempCard = m_uint8SendCardData;
				return tempCard;
			}
			for (uint8 i = 0; i < MAX_INDEX; i++)
			{
				if (m_ui8UserCardIndex[temp1][i] != 0 && (m_vecNoOutCardsIndex[ui8PlayerPosID][i] < m_ui8UserCardIndex[temp1][i]))
				{
					tempCard = m_GameLogic->SwitchToCardData(i);
					if (m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)] == 0 || m_vecNoOutCardsIndex[ui8PlayerPosID][m_GameLogic->SwitchToCardIndex(tempCard)] >= m_ui8UserCardIndex[temp1][m_GameLogic->SwitchToCardIndex(tempCard)])
						continue;
					break;
				}
			}
		

		return tempCard;
	}

	//状态变动通知
	void AIMaJiangChannelBaseInterface::SendPlayerStatus(const uint8 & ui8PlayerPosID, const uint8 & ui8Status)
	{
		WorldPacket packet;
		if (sProtocolsMgr.CreateMJPlayerStatusPacket(&packet, ui8PlayerPosID, ui8Status))
		{
			BroadcastPacket(&packet);
		}
	}

	//设置玩家状态
	void AIMaJiangChannelBaseInterface::SetPlayerStatus(CharPtr & pChr, const uint8 & playerStatus)
	{
		if (pChr.isNull()) return;
		WGS_MJCHANNEL_LOCK;

		MJBaseTablePlayer * pTp = GetTablePlayer(pChr->getHandle());
		if (pTp == NULL) return;

		pTp->status = playerStatus;
		m_ui8Trustee[pTp->pos] = playerStatus;

		SendPlayerStatus(pTp->pos, playerStatus);

	}

	//胡牌判断  ui8CurrentCard  胡的牌    
	uint8 AIMaJiangChannelBaseInterface::AnalyseHuCard(const uint8 & ui8PlayerPosID, uint8 ui8CurrentCard, CChiHuRight & ChiHuRight)
	{
		uint8	ui8Result = WIK_NULL;
		std::vector<tagAnalyseItem> AnalyseItemArray;
		ChiHuRight.SetEmpty();
		std::vector<uint8> ui8CardIndexTemp = m_ui8UserCardIndex[ui8PlayerPosID];
		std::vector<tagWeaveItem> WeaveItem = m_WeaveItemArray[ui8PlayerPosID];
		//复制手牌数据
		if (ui8CurrentCard == 0)
		{
			Log.Error("AIMaJiangChannelBaseInterface::AnalyseHuCard", "ui8CurrentCard error  :%d", ui8CurrentCard);
			return 0;
			ASSERT(0);
		}
		//将待判断的牌加入手牌
		ui8CardIndexTemp[m_GameLogic->SwitchToCardIndex(ui8CurrentCard)]++;

		ui8Result |= m_GameLogic->CheckHuPaiTypeBeforeAnalyse(ui8CardIndexTemp, WeaveItem, ui8CurrentCard, ChiHuRight);
		if (ui8Result != WIK_NULL)
		{
			CChiHuRight temp = m_ChiHuRight[ui8PlayerPosID];
			m_ChiHuRight[ui8PlayerPosID] = ChiHuRight;
			if (GetHuPaiFanXing(ui8PlayerPosID) == 0)
			{
				ui8Result = WIK_NULL;
			}
			ChiHuRight = m_ChiHuRight[ui8PlayerPosID];
			m_ChiHuRight[ui8PlayerPosID] = temp;
		}

		//分析手牌
		m_GameLogic->AnalyseCard(ui8CardIndexTemp, WeaveItem, AnalyseItemArray);

		if (AnalyseItemArray.empty() == false)
		{
			ui8Result |= WIK_CHI_HU;
			ChiHuRight |= 1;
		}
		for (uint8 i = 0; i < AnalyseItemArray.size(); i++)
		{
			tagAnalyseItem * pAnalyseItem = &AnalyseItemArray[i];
			m_GameLogic->CheckHuPaiTypeAfterAnalyse(pAnalyseItem, WeaveItem, ui8CurrentCard, ChiHuRight);
		}

		return ui8Result;
	}
	//胡牌判断  ui8CurrentCard  胡的牌    
	uint8 AIMaJiangChannelBaseInterface::AnalyseHuCard(std::vector<uint8>& ui8CardIndex, std::vector<tagWeaveItem> WeaveItem, uint8 ui8CurrentCard, CChiHuRight & ChiHuRight)
	{
		uint8	ui8Result = WIK_NULL;
		std::vector<tagAnalyseItem> AnalyseItemArray;
		ChiHuRight.SetEmpty();
		std::vector<uint8> ui8CardIndexTemp = ui8CardIndex;
		//复制手牌数据
		if (ui8CurrentCard == 0)
		{
			Log.Error("AIMaJiangChannelBaseInterface::AnalyseHuCard", "ui8CurrentCard error  :%d", ui8CurrentCard);
			return 0;
			ASSERT(0);
		}
		//将待判断的牌加入手牌
		ui8CardIndexTemp[m_GameLogic->SwitchToCardIndex(ui8CurrentCard)]++;

		ui8Result |= m_GameLogic->CheckHuPaiTypeBeforeAnalyse(ui8CardIndex, WeaveItem, ui8CurrentCard, ChiHuRight);


		//分析手牌
		m_GameLogic->AnalyseCard(ui8CardIndexTemp, WeaveItem, AnalyseItemArray);

		if (AnalyseItemArray.empty() == false)
		{
			ui8Result |= WIK_CHI_HU;
			ChiHuRight |= 1;
		}
		for (uint8 i = 0; i < AnalyseItemArray.size(); i++)
		{
			tagAnalyseItem * pAnalyseItem = &AnalyseItemArray[i];
			m_GameLogic->CheckHuPaiTypeAfterAnalyse(pAnalyseItem, WeaveItem, ui8CurrentCard, ChiHuRight);
		}

		return ui8Result;
	}
	uint8 AIMaJiangChannelBaseInterface::AnalyseHuCard(const uint8 & ui8PlayerPosID, std::vector<uint8>& ui8CardIndex, std::vector<tagWeaveItem> WeaveItem, uint8 ui8CurrentCard, CChiHuRight & ChiHuRight)
	{
		uint8	ui8Result = WIK_NULL;
		std::vector<tagAnalyseItem> AnalyseItemArray;
		ChiHuRight.SetEmpty();
		std::vector<uint8> ui8CardIndexTemp = ui8CardIndex;
		//复制手牌数据
		if (ui8CurrentCard == 0)
		{
			Log.Error("AIMaJiangChannelBaseInterface::AnalyseHuCard", "ui8CurrentCard error  :%d", ui8CurrentCard);
	/*		return 0;
			ASSERT(0);*/
		}
		//将待判断的牌加入手牌
		if(ui8CurrentCard != 0)
			ui8CardIndexTemp[m_GameLogic->SwitchToCardIndex(ui8CurrentCard)]++;
		uint8 ui8OutMagicCard = ui8CurrentCard;
		if (m_bOutMagicCard || (m_run_status == en_MJChannelState_GiveCard || (m_run_status == en_MJChannelState_OperatorCard && m_ui8CurrentPos != INVALID_uint8)))
			ui8OutMagicCard = 0;
		if (ui8OutMagicCard != 0)
		{
			std::vector<uint8> outTemp;
			outTemp.push_back(ui8OutMagicCard);
			m_GameLogic->SetMagicCardOff(outTemp);
		}
		else
		{
			std::vector<uint8> outTemp;
			m_GameLogic->SetMagicCardOff(outTemp);
		}


		ui8Result |= m_GameLogic->CheckHuPaiTypeBeforeAnalyse(ui8CardIndexTemp, WeaveItem, ui8CurrentCard, ChiHuRight);

		if (ui8Result != WIK_NULL)
		{
			CChiHuRight temp = m_ChiHuRight[ui8PlayerPosID];
			m_ChiHuRight[ui8PlayerPosID] = ChiHuRight;
			if (GetHuPaiFanXing(ui8PlayerPosID) == 0)
			{
				ui8Result = WIK_NULL;
			}
			ChiHuRight = m_ChiHuRight[ui8PlayerPosID];
			m_ChiHuRight[ui8PlayerPosID] = temp;
		}
		//分析手牌

		m_GameLogic->AnalyseCard(ui8CardIndexTemp, WeaveItem, AnalyseItemArray);

	//	m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::AnalyseHuCard","ui8Result[%d] AnalyseItemArray.size[%d] GetHuPaiFanXing(ui8PlayerPosID)[%d]", ui8Result, AnalyseItemArray.size(), GetHuPaiFanXing(ui8PlayerPosID));
		if (AnalyseItemArray.empty() == false)
		{
			ui8Result |= WIK_CHI_HU;
			ChiHuRight |= 1;
		}
		for (uint8 i = 0; i < AnalyseItemArray.size(); i++)
		{
			tagAnalyseItem * pAnalyseItem = &AnalyseItemArray[i];
			m_GameLogic->CheckHuPaiTypeAfterAnalyse(pAnalyseItem, WeaveItem, ui8CurrentCard, ChiHuRight);
		}

		return ui8Result;
	}
	std::vector<uint8> AIMaJiangChannelBaseInterface::GetTingPaiList(const uint8 & ui8PlayerPosID,const uint8 & ui8CenterCard)
	{
		std::vector<uint8> temp;
		if (m_MPlayerTingCardList[ui8PlayerPosID].size() && IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData) && m_GameLogic->AllowedTing())
		{
			if (m_MPlayerTingCardList[ui8PlayerPosID].find(ui8CenterCard) != m_MPlayerTingCardList[ui8PlayerPosID].end())
			{
				if (m_MPlayerTingCardList[ui8PlayerPosID].begin()->second.front() == 0)
				{
					/*	AnalyseTingCard(ui8PlayerPosID);*/
					std::map<uint8, std::vector<uint8> >::iterator iter;
					for (iter = m_MPlayerTingCardList[ui8PlayerPosID].begin(); iter != m_MPlayerTingCardList[ui8PlayerPosID].end(); iter++)
					{
						temp.push_back(m_GameLogic->SwitchToCardData(iter->first));
					}
					
				}
				else
				{
					temp = m_MPlayerTingCardList[ui8PlayerPosID][ui8CenterCard];
				}
			}
			else
			{
				if (m_MPlayerTingCardList[ui8PlayerPosID].begin()->second.front() == 0)
				{
					/*	AnalyseTingCard(ui8PlayerPosID);*/
					
					std::map<uint8, std::vector<uint8> >::iterator iter;
					for (iter = m_MPlayerTingCardList[ui8PlayerPosID].begin(); iter != m_MPlayerTingCardList[ui8PlayerPosID].end(); iter++)
					{
						temp.push_back(m_GameLogic->SwitchToCardData(iter->first));
					}
				
				}
				else if (m_MPlayerTingCardList[ui8PlayerPosID].begin()->second.front() != 0 && m_bBaoJiao[ui8PlayerPosID] == true)
				{
					temp = m_MPlayerTingCardList[ui8PlayerPosID].begin()->second;
				}
				else
				{
					m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
				}

			}

		}
		else if (IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData) && m_GameLogic->AllowedTing())
		{
			m_vecPlayerTingPaiTiShi[ui8PlayerPosID] = temp;
		}
		else if (IsEstimateTing(ui8PlayerPosID, m_uint8SendCardData))
		{
		
			AnalyseTingCard(ui8PlayerPosID);
		
			std::map<uint8, std::vector<uint8> >::iterator iter;
			for (iter = m_MPlayerTingCardList[ui8PlayerPosID].begin(); iter != m_MPlayerTingCardList[ui8PlayerPosID].end(); iter++)
			{
				temp.push_back(m_GameLogic->SwitchToCardData(iter->first));
			}
		}
		return temp;
	}
	//结算前的操作
	void AIMaJiangChannelBaseInterface::BeforeGameOverCalc()
	{
		Log.Debug("AIMaJiangChannelBaseInterface::BeforeGameOverCalc", "");


		CheckGameOverCalc();
	}

	bool AIMaJiangChannelBaseInterface::CheckGameOverCalc()
	{
		if (IsLiuJu())
		{
			Wait(m_nAHuPaiTime);

			SendLiangPaiInfo();


			m_next_run_status = en_MJChannelState_GameOverCalc;
			return true;
		}
		if (m_nGameModeFlag == enMJGameMode_Convention)
		{//常规模式
			SendHuPaiInfo();

			Wait(m_nAHuPaiTime);

			SendLiangPaiInfo();



			m_next_run_status = en_MJChannelState_GameOverCalc;
		}
		else if (m_nGameModeFlag == enMJGameMode_SCMJ_XLCH)
		{
		//	pTp->m_bSendHuPaiInfo = true;
		}
		else if (m_nGameModeFlag == enMJGameMode_SCMJ_XZDD)
		{

			uint8 ui8PlayerCount = 0;
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				if (m_bPlayStatus[i] == false)
				{
					ui8PlayerCount++;
				}
			}
			if (m_nMaxPlayerNum - ui8PlayerCount <= 1 || GameLoopOver())
			{
				SendHuPaiInfo();


				Wait(m_nAHuPaiTime);


				SendLiangPaiInfo();

				m_next_run_status = en_MJChannelState_GameOverCalc;
			}
			else
			{
				uint8 ui8LastHu = INVALID_uint8;
				if (m_ui8CurrentPos == ui8LastHu && m_ui8ProvideCard != ui8LastHu)
				{
					for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
					{
						uint8 l =(m_ui8ProvideCard + i + m_nMaxPlayerNum) %m_nMaxPlayerNum;
						if (m_bPlayStatus[l] == false && m_ChiHuRight[l].IsEmpty() == false && GetTablePlayerByPos(l)->m_bSendHuPaiInfo)
						{
							ui8LastHu = l;
						}
					}

				}
				SendHuPaiInfo();

				Log.Debug("AIMaJiangChannelBaseInterface::CheckGameOverCalc", "m_nFzPid[%d]  m_ui8CurrentPos:%d m_ui8ResumePos:%d ui8LastHu:%d", m_nFzPid, m_ui8ProvideCard, m_ui8ResumePos, ui8LastHu);

				Wait(m_nAHuPaiTime);

				settleAccounts();

				if (m_ui8CurrentPos == INVALID_uint8)
				{
					m_ui8CurrentPos = ui8LastHu;
				}

				VecInit<uint8>(m_bResponse, m_nMaxPlayerNum, false);
				VecInit<uint8>(m_ui8UserAction, m_nMaxPlayerNum, 0);
				VecInit<uint8>(m_ui8OperateCard, m_nMaxPlayerNum, 0);
				VecInit<uint8>(m_ui8PerformAction, m_nMaxPlayerNum, 0);
				std::vector<uint8>  m_ui8TargetCardDataTemp;
				VecInit<std::vector<uint8> >(m_ui8TargetCardData, m_nMaxPlayerNum, m_ui8TargetCardDataTemp);

				do
				{
					m_ui8CurrentPos = (m_ui8CurrentPos + m_nMaxPlayerNum FX  1) % m_nMaxPlayerNum;
				} while (m_bPlayStatus[m_ui8CurrentPos] == false);

				m_next_run_status = en_MJChannelState_GiveCard;
			}
		}
		else
		{
			Wait(m_nAHuPaiTime);

			SendLiangPaiInfo();

			m_next_run_status = en_MJChannelState_GameOverCalc;
		}

		return true;
	}

	//发送胡牌情况  
	void AIMaJiangChannelBaseInterface::SendHuPaiInfo(uint8 ui8PlyaerChairID)
	{
		Log.Debug("AIMaJiangChannelBaseInterface::SendHuPaiInfo", "");

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			Log.Debug("AIMaJiangChannelBaseInterface::SendHuPaiInfo", "i:%d ui8PlyaerChairID:%d", i, ui8PlyaerChairID);

			if (ui8PlyaerChairID == 0 || (i == ui8PlyaerChairID && ui8PlyaerChairID != 0))
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				Log.Debug("AIMaJiangChannelBaseInterface::SendHuPaiInfo", "i:%d m_ChiHuRight[i].IsEmpty():%d pTp->m_bSendHuPaiInfo:%d",i, m_ChiHuRight[i].IsEmpty(), pTp->m_bSendHuPaiInfo);

				if (pTp == NULL) continue;
				if (m_ChiHuRight[i].IsEmpty() == true || pTp->m_bSendHuPaiInfo == false)
				{//玩家没有胡牌信息

					if (m_ui8ProvidePos == i)
					{
						MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
						pTp->dianPaoNum++;
					}

					continue;
				}
				uint8 ui8HuType = enHuType_Default;
				if (IsSpecialHu(i))
				{
					ui8HuType = enHuType_HuaHu;
				}
				else if (m_ui8ProvidePos == i)
				{//如果胡牌的提供者是自己
					if (m_bGangKai)
						ui8HuType = enHuType_LingShangKaiHua;
					else
						ui8HuType = enHuType_ZiMo;
				}
				else
				{
					if (IsQiangGang())
						ui8HuType = enHuType_QiangGangHu;
					else
						ui8HuType = enHuType_Hu;
				}

				Log.Debug("AIMaJiangChannelBaseInterface::SendHuPaiInfo", "FZPID:%d m_ui8ProvidePos:%d i:%d ui8HuType:%d ",m_nFzPid, m_ui8ProvidePos, i, ui8HuType);

				std::vector<uint8 >   vecHandCard;
				if(m_ui8ChiHuCard != 0)
					m_ui8UserCardIndex[i][m_GameLogic->SwitchToCardIndex(m_ui8ChiHuCard)]--;
				m_GameLogic->SwitchToCardData(m_ui8UserCardIndex[i], vecHandCard);
				WorldPacket	packet;
				if (sProtocolsMgr.CreateMJOperateHuPacket(&packet,
					i,
					vecHandCard,
					m_WeaveItemArray[i],
					m_ui8ChiHuCard,
					GetHuPaiFanXing(i),
					m_ui8ProvidePos,
					ui8HuType,
					GetHuPaiExData(i)))
					BroadcastPacket(&packet);
				packet.clear();
				{
					packet << uint16(SMSS_MJ_OperateHu)
						<< uint16(0);
					packet << uint8(i)
						<< uint8(m_ui8ChiHuCard)
						<< uint8(ui8HuType);
					PlayBack(&packet);
				}
				if (pTp)
				{
					pTp->m_ui8ProvidePos = m_ui8ProvidePos;
					pTp->m_ui8HuPaiFanXing = GetHuPaiFanXing(i);
					pTp->m_ui8ChiHuCard = m_ui8ChiHuCard;
					pTp->m_ui8HuType = ui8HuType;
					pTp->m_ui32ExData = GetHuPaiExData(i);
					if (ui8HuType == enHuType_Hu)
						pTp->jiePaoNum++;
					if (ui8HuType == enHuType_ZiMo)
						pTp->ziMoNum++;
					if (ui8HuType == enHuType_LingShangKaiHua)
						pTp->gangshanghuaNum++;
					if (ui8HuType == enHuType_QiangGangHu)
						pTp->qiangGangNum++;
					pTp->m_bSendHuPaiInfo = false;
				}
			}

		}
	}

	//发送亮牌协议
	void AIMaJiangChannelBaseInterface::SendLiangPaiInfo()
	{
		WorldPacket packet;
		std::vector<std::vector<uint8> >   vecAllUserHandCards;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			std::vector<uint8> vecCardTemp;
			m_GameLogic->SwitchToCardData(m_ui8UserCardIndex[i], vecCardTemp);
			vecAllUserHandCards.push_back(vecCardTemp);
		}
		bool bLiuJu = IsLiuJu();
		if (m_nGameModeFlag != enMJGameMode_Convention)
		{
			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				if (m_ChiHuRight[i].IsEmpty() == false)
				{
					bLiuJu = false;
					break;
				}
			}
		}
		if (sProtocolsMgr.CreateMJLiangPaiPacket(&packet, vecAllUserHandCards, m_WeaveItemArray, bLiuJu ))
			BroadcastPacket(&packet);
	}

	//获取番型
	uint32 AIMaJiangChannelBaseInterface::GetHuPaiFanXing(const uint8 & ui8PlayerPosID)
	{
		return GetHuPaiFanXing(m_ChiHuRight[ui8PlayerPosID]);
	}

	//获取番型
	uint32 AIMaJiangChannelBaseInterface::GetHuPaiFanXing(CChiHuRight & chr)
	{
		uint8 PingHu = 1;
		return PingHu;
	}

	//获取胡牌附加数据
	uint32 AIMaJiangChannelBaseInterface::GetHuPaiExData(const uint8 & ui8PlayerPosID)
	{
		return GetHuPaiExData(m_ChiHuRight[ui8PlayerPosID]);
	}

	uint32 AIMaJiangChannelBaseInterface::GetHuPaiExData(CChiHuRight & chr)
	{
		return 0;
	}

	//结算
	void AIMaJiangChannelBaseInterface::settleAccounts()
	{
		if (IsLiuJu())
		{//判断处理流局
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DealLiuJu", "pi");
			DealLiuJu();
		}
		else
		{
			if (IsQiangGang())
			{//判断抢杠胡
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::IsQiangGang", "pi");
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(m_ui8QiangGangProvidePos);
				pTp->m_ui8HuType = enHuType_FangPao;
				DealQiangGang(m_ui8QiangGangProvidePos);

			}
			else if (IsZiMo())
			{//判断处理自摸
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DealZiMo", "pi");
				DealZiMo(m_ui8CurrentPos);
			}
			else if (IsFangPao())
			{//判断处理放炮
				m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::DealFangPao", "pi");
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(m_ui8ProvidePos);
				pTp->m_ui8HuType = enHuType_FangPao;
				DealFangPao(m_ui8ProvidePos);
			}
			else
			{
				Log.Error("AIMaJiangChannelBaseInterface::settleAccounts", "settleAccounts Error m_ui8CurrentPos;%d m_ui8ProvidePos:%d", m_ui8CurrentPos, m_ui8ProvidePos);
				ASSERT(false);
			}
		}
		m_next_run_status = en_MJChannelState_GameOverCalc;
		AttachedAccounts();
		//及时输赢
		WorldPacket packet;
		if (m_bShowConstantlyCale)
			if (sProtocolsMgr.CreateMJConstantlyCalePacket(&packet, m_vecPlayerConstantlyCaleList))
				BroadcastPacket(&packet);
		if (m_ui8NextBankerPos != m_ui8BankerPos)
		{
			m_ui8FengQuanLoopCount++;
		}
		if (m_ui8FengQuanLoopCount == m_nMaxPlayerNum)
		{
			m_ui8FengQuanLoopCount = 0;
			m_nRoundId++;
		}
		/*if (m_ui8NextBankerPos == ((m_ui8DongFengSeat + m_nMaxPlayerNum) % m_nMaxPlayerNum) && m_ui8NextBankerPos != m_ui8BankerPos )
			m_nRoundId++;*/
		Log.Debug("AIMaJiangChannelBaseInterface::settleAccounts", "m_nRoundId:%d m_ui8NextBankerPos：%d m_ui8DongFengSeat:%d", m_nRoundId, m_ui8NextBankerPos, m_ui8DongFengSeat);
		if (m_ui8PayMode == 3)
		{
			DealTongQianChang();
		}
		
	}

	//棋牌圈每局处理
	void AIMaJiangChannelBaseInterface::CenterBattleDeal()
	{
		Log.Debug("AIMaJiangChannelBaseInterface::CenterBattleDeal", "");
		WorldPacket packet;
		// 正常结束
		if (m_bNormalExit)
		{
			Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "m_bNormalExit");
			if (!m_bGameOver)
			{// 游戏未结束，进行正常的牌桌中逻辑判断
				Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "! m_bGameOver");
				// 不是解散的牌桌进行结算
				bool bDissolve = false;
				if (!m_bDissolve)
				{
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "! m_bDissolve");
					settleAccounts();

					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "! AdditionalCBData");
					AdditionalCBData();
				}
				else
				{
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "m_bDissolve");

					bDissolve = true;

					for (uint8 i = 0; i < m_nMaxPlayerNum; ++i)
					{
						uint32 pid = 0;
						MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
						if (pTp == NULL) continue;
						CharPtr pChr = sCharMgr.load(pTp->player._handle);

						UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
						if (!pUser.isNull())
							pid = pUser->getUInt32Field("platform_id");

						CenterBattlePlayerWinLose cbpw;
						cbpw.platform_id = pid;
						cbpw.char_id = pChr->getHandle();
						cbpw.vip_icon = sVipCardMgr.GetUsedVipId(pChr);
						cbpw.winLoseScore = 0;

						cbpw.player_nick = pChr->getStringField("name");
						cbpw.player_desc = pChr->getStringField("desc");

						m_btLog.player_winLose.push_back(cbpw);
					}

					if (m_nLimitLoop && m_nLoopId >= m_nLimitLoop)
						m_btLog.bFinal = true;
					else if (m_nLimitTime && m_nLimitTime >= time(0) - m_nCreateTime)
						m_btLog.bFinal = true;
					m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));
					m_btLog.mode = m_nMode;
					if (m_btLog.loop_id > m_nLimitLoop)
						m_btLog.loop_id = m_nLimitLoop;
					// 调用组局接口，更新游戏记录
					sCenterBattleLogMgr.AddCenterBattleRecordLog(m_btLog, 1);
				}

				if (m_bVoting)
				{
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "m_bVoting");

					/*if (sProtocolsMgr.CreateVoteListPacket(&packet, SendvoteList, sXmlDataMgr.getFZMJconf("VOTE_WAIT_TIME") - (time(0) - m_nVoteOverTime), enVoteFinalResult_Dissolve))
					BroadcastPacket(&packet);*/
					/*	if (sProtocolsMgr.CreateVoteResultPacket(&packet, voteType_Refuse, enVoteResult_NoUse))
					BroadcastPacket(&packet);*/
				}

				// 没有结束的话 继续游戏
				if (!CheckCenterBattleOver())
				{
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "jixu");
					//		initialize();

					StandUpPlayerGameOver();

					initialize();

					m_next_run_status = en_MJChannelState_Prep;
				}
				else
				{
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "bDissolve");

					//	if (bDissolve)
					{

						Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "sleep");
						m_next_run_status = en_MJChannelState_Close;


					}
				}
			}
			else
			{// 游戏结束将玩家都放出牌桌
				Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "m_bGameOver");





				uint8 reson = enCenterBattleReturnGold_Normal;
				if (m_nDissolveReson == DissolveType_Life)
				{// 超时
					if (m_nLoopId < 2)
						reson = enCenterBattleReturnGold_TimeOut;	// 超时结束
				}
				else if (m_nDissolveReson == DissolveType_Vote || m_nDissolveReson == DissolveType_Homeowners)
				{// 解散
					if (m_nLoopId < 1)
						reson = enCenterBattleReturnGold_OwnerDissolve;
				}
				m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));
				m_btLog.mode = m_nMode;
				sCenterBattleLogMgr.CountBattleLogUseTime(m_btLog.cb_id);	// 设置牌桌结束时间
				sCenterBattleMgr.CenterBattleComplate(m_btLog.cb_id, reson);

				m_next_run_status = en_MJChannelState_Close;
			}

			if (m_next_run_status == en_MJChannelState_Close)
			{
				Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "en_ChannelRun_Done");
				m_bPause = false;

				for (uint8 i = 0; i < m_nMaxPlayerNum; ++i)
				{

					MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
					if (pTp == NULL) continue;
					CharPtr pChr = sCharMgr.load(pTp->player._handle);
					if (pChr.isNull())  continue;
					/*if (pChr.isNull())
					pChr = sCharMgr.load((*itSeat).char_id);*/
					Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "Chr:%d FREE time:%d", pChr->getHandle(), now());
					pChr->setStatus(CharacterStatusFree);
					AICreatureBaseInterface* pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
					if (pChrAiInfe)
					{
						pChrAiInfe->SetTownNull();
						pChrAiInfe->SetChannelNull();

						/* WorldPacket packet;
						// 发送玩家退出房间
						if(sProtocolsMgr.CreateExitReturnHallPacket(&packet,true))
						sGLMgr.SendProtocolsToChr(pChr, &packet); */
					}
					pChr->SaveDB();
				}


				m_Unit->setUInt32Field("timeout", time(0));
				m_Unit->setUInt32Field("status", (uint32)Channel::ChannelStatusDone);
				m_Unit->SaveDB();
				// 删除牌桌
				setRunStatus(en_MJChannelState_Close);

				//if (m_bDissolve)
				//{// 解散牌桌原因
				//	if (sProtocolsMgr.CreateDissolveChannelPacket(&packet, m_nDissolveReson))
				//		BroadcastPacket(&packet);
				//}
				if (m_nDissolveReson == DissolveType_Loop || DissolveType_ClubRoomTimesUp == m_nDissolveReson)
				{
					setStatusEndTimer(m_GameLogic->GetChannelTime("BattleOverWait"));
				}
				else
				{
					setStatusEndTimer(500);
				}
				/*uint32 n_t = now();
				while (n_t > now())
				{

				}
				Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "channel[%d] jieshu time:%d",m_Unit->getHandle(),now());*/

				return;
			}
			else
			{// 重新开始新的一轮
			 // 检查有托管或者离线的玩家

				return;
			}
		}
		else
		{// 调用接口牌局结束
			Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "! m_bNormalExit");

			m_Unit->setUInt32Field("timeout", time(0));
			m_Unit->setUInt32Field("status", (uint32)Channel::ChannelStatusDone);
			m_Unit->SaveDB();

			for (uint8 i = 0; i < m_nMaxPlayerNum; ++i)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL) continue;
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr.isNull())  continue;

				Log.Debug("AIMaJiangChannelBaseInterface::ChannelBattleCalcAndWaitUpdate", "Chr:%d FREE now:%d", pChr->getHandle(), now());
				pChr->setStatus(CharacterStatusFree);
				AICreatureBaseInterface* pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
				if (pChrAiInfe)
				{
					pChrAiInfe->SetTownNull();
					pChrAiInfe->SetChannelNull();

					/* WorldPacket packet;
					// 发送玩家退出房间
					if(sProtocolsMgr.CreateExitReturnHallPacket(&packet,true))
					sGLMgr.SendProtocolsToChr(pChr, &packet); */
				}
			}
			uint8 reson = enCenterBattleReturnGold_Normal;
			if (m_bDissolve)
			{
				if (m_nLoopId < 1)
					reson = enCenterBattleReturnGold_OwnerDissolve;
			}
			m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));
			m_btLog.mode = m_nMode;
			sCenterBattleLogMgr.CountBattleLogUseTime(m_btLog.cb_id);	// 设置牌桌结束时间
			sCenterBattleMgr.CenterBattleComplate(m_btLog.cb_id, reson);

			// 删除牌桌

		}

		if (m_bGameOver == true)
		{
			// 删除牌桌
			setRunStatus(en_MJChannelState_Close);

			m_next_run_status = en_MJChannelState_Close;
			return;
		}

		m_next_run_status = en_MJChannelState_Prep;
		return;

	}

	//棋牌圈数据
	void AIMaJiangChannelBaseInterface::AdditionalCBData()
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::AdditionalCBData", "m_nMaxPlayerNum:%d", m_nMaxPlayerNum);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			Log.Debug("AIMaJiangChannelBaseInterface::AdditionalCBData", "i:%d", i);
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp == NULL) continue;
			CharPtr pChr = sCharMgr.load(pTp->player._handle);
			if (pChr.isNull()) continue;
			uint32 pid = 0;
			UserPtr  pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
			if (pUser.isNull() == false)
			{
				pid = pUser->getUInt32Field("platform_id");
			}
			CenterBattlePlayerWinLose cbpw;
			if (pChr->isNPC() == false)
				cbpw.platform_id = pid;
			else
				cbpw.platform_id = pChr->getUInt32Field("motion");
			cbpw.char_id = pChr->getHandle();
			cbpw.vip_icon = sVipCardMgr.GetUsedVipId(pChr);
			cbpw.winLoseScore = pTp->winLurce;
			Log.Debug("AIMaJiangChannelBaseInterface::AdditionalCBData", "cbpw.winLoseScore:%d  pTp->score:%d", cbpw.winLoseScore, pTp->score);
			cbpw.player_nick = pChr->getStringField("name");
			cbpw.player_desc = pChr->getStringField("desc");
			Json::Value val;
			val["score"] = pTp->winLurce;
			uint8 ui8ming = 0, ui8an = 0, ui8bu = 0;
			for (uint8 j = 0; j < m_WeaveItemArray[i].size(); j++)
			{
				Json::Value weaveTemp;
				weaveTemp["type"] = m_WeaveItemArray[i][j].ui8WeaveKind;
				weaveTemp["card"] = m_WeaveItemArray[i][j].ui8CenterCard;
				weaveTemp["exdata"] = m_WeaveItemArray[i][j].ui8Type;
				val["cpgs"].append(weaveTemp);
				if (m_WeaveItemArray[i][j].ui8WeaveKind == WIK_GANG)
				{
					if (m_WeaveItemArray[i][j].ui8Type == enGangType_AnGang)
					{
						ui8an++;
					}
					else if (m_WeaveItemArray[i][j].ui8Type == enGangType_MingGang)
					{
						ui8ming++;
					}
					else
						ui8bu++;
				}

			}
			std::vector<uint8> v_Card, v_HandCard;
			v_HandCard = m_ui8UserCardIndex[i];
			m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::AdditionalCBData", "v_HandCard:%d", v_HandCard.size());

			if (m_ChiHuRight[i].IsEmpty() == false)
			{
				val["hupaicard"] = pTp->m_ui8ChiHuCard;
			}
			m_GameLogic->SwitchHandIndexToCardData(v_HandCard, v_Card);
			String sCard = "";
			for (size_t t = 0; t < v_Card.size(); t++)
			{
				if (t != v_Card.size() - 1)
					sCard += StringConverter::toString(v_Card[t]) + ",";
				else
					sCard += StringConverter::toString(v_Card[t]);
			}
			val["handcard"] = Json::Value(sCard);
			val["operate"] = Json::Value(pTp->m_ui8HuType);
			val["type"] = Json::Value(pTp->m_ui8HuPaiFanXing);
			//	val["exdata"] = Json::Value(PlayerScore[i].ui32ExData);
			val["isbanker"] = bool(i == m_ui8BankerPos);
			Json::Value gameDate;
			AdditionalGameServerCBData(gameDate);
			val["GameServerDate"] = gameDate;
			CustomJsonData(pTp, val);
			cbpw.json_data = Json::FastWriter().write(val);
			m_btLog.player_winLose.push_back(cbpw);
		}

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp == NULL) continue;
			CharPtr pChr = sCharMgr.load(pTp->player._handle);
			if (pChr.isNull()) continue;
			Json::Value val;
			CustomCenterDBJsonData(pTp, val);
			String sInfo = Json::FastWriter().write(val);
			sFriendRecordMgr.CommitPlayerInfoToCenter(pChr, sInfo, 1);
		}



		if (m_nLimitLoop && m_nLoopId >= m_nLimitLoop)
		{// 轮数限制到
			m_btLog.bFinal = true;
			m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));

		}
		else if (m_nLimitTime && m_nLimitTime >= time(0) - m_nCreateTime)
		{// 时间限制到
			m_btLog.bFinal = true;
			m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));

		}

		if (m_btLog.bFinal == true)
		{

			for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
			{
				MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
				if (pTp == NULL) continue;
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr.isNull()) continue;
				// 提交最终输赢总结果
				sFriendRecordMgr.CommitFinalCenterBattleData(pChr, m_nMode, m_nGameID, pTp->score);
			}
		}

		// 调用组局接口，更新游戏记录
		m_GameLogData[ROOMINFO]["isliuju"] = IsLiuJu();
		m_btLog.record_data = Json::FastWriter().write(m_GameLogData);
		m_btLog.bHaveVedio = m_GameLogic->IsHaveVedio();
		m_btLog.loop_id = m_nLoopId;
		if(m_ui8RoundMode != enRoundMode_QuanShu)
			if (m_btLog.loop_id > m_nLimitLoop)
				m_btLog.loop_id = m_nLimitLoop;
		m_btLog.mode = m_nMode;
		m_btLog.create_time = sGLMgr.GetCurDateTime(time(0));
		sCenterBattleLogMgr.AddCenterBattleRecordLog(m_btLog, 1);
		m_btLog.player_winLose.clear();

	}

	void AIMaJiangChannelBaseInterface::CustomJsonData(MJBaseTablePlayer * pTp, Json::Value & val)
	{
		{
			Json::Value temp;
			temp["杠牌次数"] = pTp->anGangNum + pTp->mingGangNum + pTp->buGangNum;
			val["tongji"].append(temp);
		}
		{
			Json::Value temp;
			temp["胡牌局数"] = pTp->ziMoNum + pTp->jiePaoNum;
			val["tongji"].append(temp);
		}
		{
			Json::Value temp;
			temp["自摸次数"] = pTp->ziMoNum;
			val["tongji"].append(temp);
		}
		{
			Json::Value temp;
			temp["放炮次数"] = pTp->dianPaoNum;
			val["tongji"].append(temp);
		}

	}

	bool AIMaJiangChannelBaseInterface::GameLoopOver()
	{
		m_GameLogic->LogDeBug("AIMaJiangChannelBaseInterface::GameLoopOver", "GameLoopOver channel[%d]",m_Unit->getHandle());
		return IsLiuJu();
	}

	//流局判断
	bool AIMaJiangChannelBaseInterface::IsLiuJu() 
	{ 
		//无人胡牌  &&  剩余牌数等于流局牌数
		/*bool bLiuju = false;
		uint8 ui8PlayerNum = 0;
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			if (GetTablePlayerByPos(i)->m_ui8ChiHuCard != 0)
			{
				ui8PlayerNum++;
			}
		}
		if (ui8PlayerNum >= 0 && ui8PlayerNum <= 2)
		{
			bLiuju = true;
		}*/
		//return (bLiuju &&  m_uint8LeftCardCount == m_ui8LiuJuCardNum);
		return ( (IsQiangGang() == false && IsFangPao() == false && IsZiMo()== false ) &&  m_uint8LeftCardCount == m_ui8LiuJuCardNum);
	}
	void AIMaJiangChannelBaseInterface::DealLiuJu()
	{
		m_ui8NextBankerPos = (m_ui8BankerPos FX 1 + m_nMaxPlayerNum) % m_nMaxPlayerNum;
	}

	bool AIMaJiangChannelBaseInterface::IsSpecialHu(const uint8 & ui8PlayerPos)
	{
		return false;
	}

	//抢杠
	bool AIMaJiangChannelBaseInterface::IsQiangGang()
	{
		return (m_bGangStatus && m_ui8QiangGangProvidePos != INVALID_uint8);
	}
	void AIMaJiangChannelBaseInterface::DealQiangGang(const uint8 & ui8ProvidePos)
	{
	}

	//自摸
	bool AIMaJiangChannelBaseInterface::IsZiMo()
	{
		return (m_ui8ProvidePos == m_ui8CurrentPos);
	}
	void AIMaJiangChannelBaseInterface::DealZiMo(const uint8 & ui8CurrentPos)
	{
	}

	//岭上开花
	bool AIMaJiangChannelBaseInterface::IsLingShangKaiHua()
	{
		return m_bGangKai && IsZiMo();
	}
	void AIMaJiangChannelBaseInterface::DealLingShangKaiHua(const uint8 & ui8CurrentPos)
	{
	}
	//放炮
	bool AIMaJiangChannelBaseInterface::IsFangPao()
	{
		return (m_ui8CurrentPos == INVALID_uint8);
	}
	void AIMaJiangChannelBaseInterface::DealFangPao(const uint8 & ui8ProvidePos)
	{
	}
	//追加处理
	void AIMaJiangChannelBaseInterface::AttachedAccounts()
	{
	}
	//铜钱场追加处理
	void AIMaJiangChannelBaseInterface::DealTongQianChang()
	{
		CenterBattle cb;
		sCenterBattleMgr.GetCenterBattle(m_btLog.cb_id, &cb);
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp)
			{
				CharPtr pChr = sCharMgr.load(pTp->player._handle);
				if (pChr.isNull() == false)
				{
					if(m_btLog.club_id != 0)
					{
						if(sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id,pChr) == 0)
						{// 游戏中，俱乐部那边已经将自己退分了
							pTp->m_bClearClubScore = true;
						}
					}
					
					if (pTp->winLurce > 0)
					{
						if (m_btLog.club_id == 0)
							sGLMgr.addItemNum(pChr, cb.data1, pTp->winLurce);
						else
							sCenterClubMemberMgr.AddMemberCurrCoins(m_btLog.club_id, pChr, pTp->winLurce);
						sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Game, cb.data1, en_UNT_Add, pTp->winLurce, m_btLog.cb_id, m_Unit->getHandle());
					}
					else if (pTp->winLurce < 0)
					{
						if (m_btLog.club_id == 0)
						{
							if (sGLMgr.GetItemNum(pChr, cb.data1) > uint32(-pTp->winLurce))
								sGLMgr.reduceItemNum(pChr, cb.data1, uint32(-pTp->winLurce));
							else
								sGLMgr.SetItemNum(pChr, cb.data1, 0);
						}
						else
						{
							if (sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id,pChr) > (-pTp->winLurce))
								sCenterClubMemberMgr.ReduceMemberCurrCoins(m_btLog.club_id, pChr, -pTp->winLurce);
							else
								sCenterClubMemberMgr.ReduceMemberCurrCoins(m_btLog.club_id, pChr, sCenterClubMemberMgr.GetMemberCurrCoins(m_btLog.club_id, pChr));
						}
						

						sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Game, cb.data1, en_UNT_Reduce, (-pTp->winLurce), m_btLog.cb_id, m_Unit->getHandle());
					}
					WorldPacket packet;
					if (sProtocolsMgr.CreateMJPlayerInfoPacket(&packet, pTp))
						sGLMgr.SendProtocolsToChr(pChr, &packet);
				}
			}
		}
	}
	//回放记录
	void AIMaJiangChannelBaseInterface::PlayBack(WorldPacket * pPacket)
	{
		if (pPacket == NULL) return;
		uint16 code;
		*pPacket >> code;
		uint16 splen;
		*pPacket >> splen;

		Json::Value temp;
		switch (code)
		{
		case SMSS_MJ_GiveCard:
		{
			uint8 ui8PlayerPos = 0, ui8CardData = 0;
			*pPacket >> ui8PlayerPos >> ui8CardData;
			temp["code"] = enPlayBack_GiveCard;
			temp["pos"] = ui8PlayerPos;
			temp["card"] = ui8CardData;
		}
		break;
		case SMSS_MJ_OutCardForAllPlayer:
		{
			uint8 ui8PlayerPos = 0, ui8CardData = 0;
			*pPacket >> ui8PlayerPos >> ui8CardData;
			temp["code"] = enPlayBack_OutCard;
			temp["pos"] = ui8PlayerPos;
			temp["card"] = ui8CardData;
			// enPlayBack_ChiPengGang;
		}
		break;
		case SMSS_MJ_OperateChiPengGang:
		{
			uint8 ui8PlayerPos = 0, ui8CardData = 0, ui8ProvidePos = 0, ui8WeaveKind = 0, ui8Type = 0;
			*pPacket >> ui8PlayerPos >> ui8WeaveKind >> ui8ProvidePos >> ui8CardData >> ui8Type;
			uint8 ui8CardNum = 0;
			*pPacket >> ui8CardNum;
			std::vector<uint8> vecCardList;
			for (uint8 i = 0; i < ui8CardNum; i++)
			{
				uint8 CardTemp = 0;
				*pPacket >> CardTemp;
				vecCardList.push_back(CardTemp);
			}
			temp["code"] = enPlayBack_ChiPengGang;
			temp["pos"] = ui8PlayerPos;
			temp["operate"] = ui8WeaveKind;
			temp["type"] = ui8Type;
			temp["cards"] = sGLMgr.split(vecCardList.begin(), vecCardList.end(), ',');
		}
		break;
		case SMSS_MJ_OperateListen:
		{
			uint8 ui8PlayerPos = 0;
			*pPacket >> ui8PlayerPos;
			temp["code"] = enPlayBack_Listen;
			temp["pos"] = ui8PlayerPos;

		}
		break;
		case SMSS_MJ_OperateHu:
		{
			uint8 ui8PlayerPos = 0, ui8CenterCard = 0, ui8HuType = 0;
			*pPacket >> ui8PlayerPos >> ui8CenterCard >> ui8HuType;
			temp["code"] = enPlayBack_Hu;
			temp["pos"] = ui8PlayerPos;
			temp["card"] = ui8CenterCard;
			temp["type"] = ui8HuType;
		}
		break;
		}
		if(temp.isNull() == false)
			m_GameLogData[GAMEINFO].append(temp);
		else
		{
			Log.Error("AIMaJiangChannelBaseInterface::GameLog", "cb_id:%d Code[%x] Not Find", m_btLog.cb_id, code);
		}
	}

	//游戏开始数据
	void AIMaJiangChannelBaseInterface::LogGameStart()
	{
		Json::Value value;

		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp == NULL) continue;
			CharPtr pChr = sCharMgr.load(pTp->player._handle);
			if (pChr.isNull()) continue;
			String name = pChr->getStringField("name");
			String head = pChr->getStringField("desc");
			uint32 sex = pChr->getUInt32Field("sex");
			uint32 score = pTp->score;
			uint32 money = sGLMgr.GetItemNum(pChr, ItemModel_Coins);
			UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
			uint32 pid = 0;
			String addr = "";
			if (pUser.isNull() == false)
			{
				pid = pUser->getUInt32Field("platform_id");
				addr = pUser->getStringField("addr");
			}
			Json::Value temp;
			temp["name"] = name;
			temp["head"] = head;
			temp["sex"] = sex;
			temp["addr"] = addr;
			temp["pid"] = pid;
			temp["seat"] = i;
			temp["score"] = score;
			temp["money"] = money;

			value[PLAYERINFO].append(temp);
		}

		value[ROOMINFO]["Rule"] = m_strPlayJsonData;
		value[ROOMINFO]["DongFeng"] = m_ui8DongFengSeat;
		value[ROOMINFO]["CardNum"] = m_uint8LeftCardCount;
		value[ROOMINFO]["Banker"] = m_ui8BankerPos;
		value[ROOMINFO]["qiang_start_seat"] = (m_dice[0] + m_dice[1]) % m_nMaxPlayerNum;
		value[ROOMINFO]["qiang_start_num"] = m_dice[2] + m_dice[3];

		m_GameLogData.clear();
		m_GameLogData = value;
	}

	//记录玩家手牌
	void AIMaJiangChannelBaseInterface::LogPlayerHandCars()
	{
		for (uint8 i = 0; i < m_nMaxPlayerNum; i++)
		{
			MJBaseTablePlayer * pTp = GetTablePlayerByPos(i);
			if (pTp == NULL) continue;
			String sCard = "";
			for (size_t t = 0; t < pTp->m_vecHandCardsList.size(); t++)
			{
				if (t != pTp->m_vecHandCardsList.size() - 1)
					sCard += StringConverter::toString(pTp->m_vecHandCardsList[t]) + ",";
				else
					sCard += StringConverter::toString(pTp->m_vecHandCardsList[t]);
			}
			m_GameLogData[PLAYERINFO][i]["InitHandCards"] = sCard;

			std::vector<uint8> v_Card, v_HandCard;
			v_HandCard = m_ui8UserCardIndex[i];
			
			m_GameLogic->SwitchHandIndexToCardData(v_HandCard, v_Card);
			sCard = "";
			for (size_t t = 0; t < v_Card.size(); t++)
			{
				if (t != v_Card.size() - 1)
					sCard += StringConverter::toString(v_Card[t]) + ",";
				else
					sCard += StringConverter::toString(v_Card[t]);
			}
			m_GameLogData[PLAYERINFO][i]["HandCards"] = sCard;
			m_GameLogData[PLAYERINFO][i]["charId"] = pTp->player._handle;

		}
	}


	//========================对外接口=======================

	//获取手牌列表
	std::map<uint32, uint32> AIMaJiangChannelBaseInterface::GetHandCards(uint8 pos)
	{
		std::map<uint32, uint32> cardTemp;
		for (uint8 i = 0; i < MAX_INDEX; i++)
		{
			cardTemp[m_GameLogic->SwitchToCardData(i)] = m_ui8UserCardIndex[pos][i];
		}
		return cardTemp;
	}

	//获取吃碰杠列表
	std::vector<tagWeaveItem>& AIMaJiangChannelBaseInterface::GetWeaveList(uint8 pos)
	{
		return m_WeaveItemArray[pos];
	}

	std::vector<uint32> AIMaJiangChannelBaseInterface::GetDiscardCardsList(uint8 pos)
	{
		std::vector<uint32 > cardTemp;
		for (uint8 i = 0; i < m_ui8DiscardCard[pos].size(); i++)
		{
			cardTemp.push_back(m_ui8DiscardCard[pos][i]);
		}
		return cardTemp;
	}

	uint8 AIMaJiangChannelBaseInterface::GetAction(uint8 pos)
	{
		return m_ui8UserAction[pos];
	}

	void AIMaJiangChannelBaseInterface::SetAction(uint8 pos, const uint8 & ui32Action)
	{
		m_ui8UserAction[pos] |= ui32Action;
	}

	void AIMaJiangChannelBaseInterface::CleanAction(uint8 pos)
	{
		m_ui8UserAction[pos] = WIK_NULL;
	}

	void AIMaJiangChannelBaseInterface::AddCard(uint8 pos, const uint32 card, uint32 num)
	{
		m_ui8UserCardIndex[pos][m_GameLogic->SwitchToCardIndex(card)] += num;
	}

	void AIMaJiangChannelBaseInterface::RemoveCard(uint8 pos, const uint32 card, uint32 num)
	{
		if (m_ui8UserCardIndex[pos][m_GameLogic->SwitchToCardIndex(card)] >= num)
			m_ui8UserCardIndex[pos][m_GameLogic->SwitchToCardIndex(card)] -= num;
		else
			m_ui8UserCardIndex[pos][m_GameLogic->SwitchToCardIndex(card)] = 0;
	}

	void AIMaJiangChannelBaseInterface::SetCardNum(uint8 pos, const uint32 card, uint32 num)
	{
		m_ui8UserCardIndex[pos][m_GameLogic->SwitchToCardIndex(card)] = num;
	}

	void AIMaJiangChannelBaseInterface::AddChiPengGang(uint8 pos, tagWeaveItem & Weave)
	{
		m_WeaveItemArray[pos].push_back(Weave);
	}

	bool AIMaJiangChannelBaseInterface::CheckPlayerHuPai(uint8 pos)
	{
		std::vector<uint8 > cardTemp = m_ui8UserCardIndex[pos];

		uint8 cardCount = m_GameLogic->GetCardCount(cardTemp);
		if (cardCount != 14) return false;

		for (uint8 i = 0; i < MAX_INDEX; i++)
		{
			if (cardTemp[i] != 0)
			{
				uint8 Card = m_GameLogic->SwitchToCardData(i);
				cardTemp[i] --;
				CChiHuRight chr;
				if (WIK_CHI_HU == AnalyseHuCard(pos, Card, chr))
				{
					return true;
				}
				cardTemp[i] ++;
			}
		}

		return false;
	}

	//检测是否可以听牌
	bool AIMaJiangChannelBaseInterface::CheckPlayerTingPai(uint8 pos)
	{
		return (WIK_LISTEN == AnalyseTingCard(pos));
	}
	bool AIMaJiangChannelBaseInterface::CheckPlayerChiPai(uint8 pos, uint32 card)
	{
		return (WIK_NULL != m_GameLogic->EstimateChiCard(m_ui8UserCardIndex[pos], card, m_VPlayerChiCardList[pos]));
	}
	bool AIMaJiangChannelBaseInterface::CheckPlayerPengPai(uint8 pos, uint32 card)
	{
		return (WIK_NULL != m_GameLogic->EstimatePengCard(m_ui8UserCardIndex[pos], card, m_VPlayerPengCardList[pos]));
	}
	bool AIMaJiangChannelBaseInterface::CheckPlayerGangPai(uint8 pos)
	{
	//	return (WIK_NULL != m_GameLogic->AnalyseGangCard(m_ui8UserCardIndex[pos], m_WeaveItemArray[pos], m_VPlayerGangCardList[pos]));
		return  true;
	}
	bool AIMaJiangChannelBaseInterface::CheckPlayerGangPai(uint8 pos, uint32 card)
	{
		return (WIK_NULL != m_GameLogic->EstimateGangCard(m_ui8UserCardIndex[pos], card, m_VPlayerGangCardList[pos]));
	}
}
#endif // MJPUBLIC






